123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:get/get.dart';
- import 'alert_dialog.dart';
- /// 小弹窗输入
- class VDialogNumber extends StatefulWidget {
- /// 标题
- final String? title;
- /// 描述
- final String? description;
- /// 输入占位符
- final String? placeholder;
- /// 初始值
- final String? initialValue;
- const VDialogNumber({
- Key? key,
- this.title,
- this.description,
- this.placeholder,
- this.initialValue,
- }) : super(key: key);
- @override
- State<VDialogNumber> createState() => _VDialogNumberState();
- Future<String?> show<String>() => VAlertDialog.showDialog<String>(this);
- }
- class _VDialogNumberState extends State<VDialogNumber> {
- late TextEditingController _controller;
- double _value = 0;
- @override
- void initState() {
- super.initState();
- _controller = TextEditingController(text: widget.initialValue);
- _value = double.tryParse(_controller.text) ?? 0;
- }
- @override
- Widget build(BuildContext context) {
- return VAlertDialog(
- title: widget.title,
- width: 440,
- contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24),
- content: _buildContent(context),
- showCancel: true,
- onConfirm: () {
- Get.back(result: _controller.text);
- },
- );
- }
- Widget _buildContent(BuildContext context) {
- final children = <Widget>[];
- if (widget.description != null) {
- children.add(
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: 4),
- child: Text(
- widget.description!,
- style: const TextStyle(color: Colors.black87, fontSize: 18),
- ),
- ),
- );
- children.add(const SizedBox(height: 8));
- } else {
- children.add(const SizedBox(height: 12));
- }
- children.add(_buildInputWidget(context));
- return SingleChildScrollView(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: children,
- ),
- );
- }
- Widget _buildInputWidget(BuildContext context) {
- const fontSize = 20.0;
- const height = 56.0;
- return SizedBox(
- height: height,
- child: Row(
- children: [
- IconButton(
- icon: Icon(
- Icons.remove,
- color: _value == 0 ? Colors.grey : Theme.of(context).primaryColor,
- ),
- onPressed: _value == 0
- ? null
- : () {
- setState(() {
- _value = (_value - 1).clamp(0, 999); // 减1,并限制在0到999之间
- _controller.text = _value.toString();
- _moveCursorToEnd();
- });
- },
- ),
- Expanded(
- child: TextField(
- controller: _controller,
- readOnly: false,
- textAlign: TextAlign.center,
- autofocus: true,
- keyboardType: const TextInputType.numberWithOptions(
- decimal: true), // 允许输入数字和小数点
- inputFormatters: [
- FilteringTextInputFormatter.allow(
- RegExp(r'^\d+\.?\d{0,2}'),
- ), // 只允许输入数字和小数点,俩位小数
- ],
- style: const TextStyle(fontSize: fontSize),
- decoration: InputDecoration(
- border: const UnderlineInputBorder(
- borderRadius: BorderRadius.zero,
- borderSide: BorderSide(),
- ),
- enabledBorder: const UnderlineInputBorder(
- borderRadius: BorderRadius.zero,
- borderSide: BorderSide(
- color: Colors.black54,
- ),
- ),
- focusedBorder: UnderlineInputBorder(
- borderRadius: BorderRadius.zero,
- borderSide: BorderSide(
- color: Theme.of(context).primaryColor.withOpacity(.4),
- ),
- ),
- filled: true,
- fillColor: Colors.white,
- contentPadding: const EdgeInsets.symmetric(
- vertical: (height - fontSize * 1.2) / 2,
- horizontal: 8,
- ),
- hintStyle: const TextStyle(fontSize: fontSize),
- labelStyle: const TextStyle(fontSize: fontSize),
- hintText: widget.placeholder,
- isCollapsed: true,
- ),
- onChanged: (value) {
- setState(() {
- _value = double.tryParse(value) ?? 0; // 将_value的类型改为double
- });
- },
- onSubmitted: (value) {
- Get.back(result: value);
- },
- ),
- ),
- IconButton(
- icon: Icon(
- Icons.add,
- color:
- _value == 999 ? Colors.grey : Theme.of(context).primaryColor,
- ),
- onPressed: _value == 999
- ? null
- : () {
- setState(() {
- _value = (_value + 1).clamp(0, 999); // 加1,并限制在0到999之间
- _controller.text = _value.toString();
- _moveCursorToEnd();
- });
- },
- ),
- ],
- ),
- );
- }
- void _moveCursorToEnd() {
- final text = _controller.text;
- _controller.value = _controller.value.copyWith(
- selection: TextSelection.collapsed(offset: text.length),
- );
- }
- }
|