Flutter TextFormField价格输入格式化需求:自动补两位小数并限制输入长度
Flutter TextFormField价格输入格式化需求:自动补两位小数并限制输入长度
我明白你现在的需求啦——要做一个价格输入框,输入数字时自动补两位小数(比如输入1显示1.00,输入123显示12.30),还得限制最长是5个字符(比如12.30这种格式)。先看看你现有代码里的几个小问题,再给你调整后的完整方案:
现有代码的几个问题
- onChanged赋值错误:
fuelPrice = (fuelPriceValue as TextEditingController);这里完全不对,fuelPriceValue是输入的字符串,不能直接转成TextEditingController类型,应该直接操作controller的文本或者按需处理字符串。 - 长度限制不匹配:你要的最终格式是
XX.XX(5个字符),但现有代码里用了LengthLimitingTextInputFormatter(4),会导致格式化后的文本被截断。 - 缺少自动补零逻辑:输入1-2位数字时,没有自动补全末尾的
.00,不符合价格字段的需求。
修正后的完整代码
// 记得提前初始化controller final TextEditingController fuelPrice = TextEditingController(); // 价格输入框 TextFormField( validator: (fuelPriceValue) { if (fuelPriceValue!.isEmpty) { return null; } // 可以加额外的校验,比如价格不能为0 if (double.tryParse(fuelPriceValue) == 0) { return "价格不能为0"; } return null; }, onChanged: (value) { // 如果需要把格式化后的价格转成数字做后续处理 final double? price = double.tryParse(value); if (price != null) { // 这里写你的业务逻辑,比如更新状态变量 } }, controller: fuelPrice, keyboardType: TextInputType.number, inputFormatters: [ // 限制最终显示的文本长度为5(比如XX.XX) LengthLimitingTextInputFormatter(5), // 只允许输入数字 FilteringTextInputFormatter.allow(RegExp(r'\d*')), // 自定义格式化逻辑 TextInputFormatter.withFunction((oldValue, newValue) { // 过滤掉所有非数字字符,只保留纯数字 final digitsOnly = newValue.text.replaceAll(RegExp(r'[^0-9]'), ''); String formattedText; switch (digitsOnly.length) { case 0: formattedText = ''; break; case 1: // 输入1位数字 → X.00 formattedText = '${digitsOnly[0]}.00'; break; case 2: // 输入2位数字 → XX.00 formattedText = '$digitsOnly.00'; break; case 3: // 输入3位数字 → X.XX formattedText = '${digitsOnly.substring(0,1)}.${digitsOnly.substring(1)}'; break; case 4: // 输入4位数字 → XX.XX formattedText = '${digitsOnly.substring(0,2)}.${digitsOnly.substring(2)}'; break; default: // 超过4位数字,只取前4位处理 final trimmedDigits = digitsOnly.substring(0,4); formattedText = '${trimmedDigits.substring(0,2)}.${trimmedDigits.substring(2)}'; break; } // 确保光标始终在文本末尾,避免格式化后光标跳错位置 final cursorPosition = formattedText.length; return TextEditingValue( text: formattedText, selection: TextSelection.collapsed(offset: cursorPosition), ); }), ], decoration: const InputDecoration( errorBorder: OutlineInputBorder(), border: OutlineInputBorder(), contentPadding: EdgeInsets.only(left: 10), hintText: "输入价格", // 可以加个提示文本 ), );
代码逻辑说明
- 输入过滤:先用
FilteringTextInputFormatter确保只能输入数字,再在自定义formatter里二次过滤,避免意外字符干扰。 - 格式化规则:根据输入的数字位数自动转换为带两位小数的格式,完全符合你要的价格显示需求。
- 光标处理:格式化后强制光标在文本末尾,避免用户输入时光标乱跑的问题。
- 长度限制:用
LengthLimitingTextInputFormatter(5)限制最终显示的文本长度,刚好匹配XX.XX的格式。
备注:内容来源于stack exchange,提问作者Quentinio
相关产品推荐
相关产品推荐

