如何确保TextFormField输入为合法数字并解决FormatException问题
解决TextFormField输入Double时的异常与无效输入问题
一、先解决FormatException异常
你当前的onChanged会在用户每输入一个字符就触发解析,比如输入-还没输数字时,double.parse("-")必然报错。直接用double.tryParse替代即可,它在解析失败时返回null,不会抛出异常:
onChanged:(value) { setState(() { fieldPointX = double.tryParse(value) ?? fieldPointX; // 解析失败就保留原有值 }); }
二、阻止无效输入(多减号/多小数点等)
默认的FilteringTextInputFormatter正则太宽松,得自定义一个输入格式化器来严格限制输入规则:
1. 自定义输入格式化器
创建一个ValidDoubleInputFormatter类,实现以下规则:
- 减号只能有一个,且必须在字符串开头
- 小数点只能有一个,不能单独出现在开头(除非前面带减号)
- 过滤连续的无效字符(如
--、..、3-等)
class ValidDoubleInputFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { String newText = newValue.text; if (newText.isEmpty) return newValue; // 处理多个减号:仅保留开头的一个 if (newText.startsWith('-')) { newText = '-' + newText.substring(1).replaceAll('-', ''); } else { newText = newText.replaceAll('-', ''); } // 处理多个小数点:仅保留第一个 int dotCount = newText.split('.').length - 1; if (dotCount > 1) { int firstDotIndex = newText.indexOf('.'); newText = newText.substring(0, firstDotIndex + 1) + newText.substring(firstDotIndex + 1).replaceAll('.', ''); } // 处理开头是小数点的情况:自动补0(如.123→0.123,-.123→-0.123) if (newText.startsWith('.') && newText.length > 1) { newText = '0' + newText; } if (newText.startsWith('-.') && newText.length > 2) { newText = '-0' + newText.substring(1); } return TextEditingValue( text: newText, selection: TextSelection.collapsed(offset: newText.length), ); } }
2. 替换原TextFormField的配置
把原来的inputFormatters换成自定义的格式化器,同时优化键盘类型:
TextFormField( inputFormatters: [ValidDoubleInputFormatter()], keyboardType: TextInputType.numberWithOptions(decimal: true), // 适配小数输入的键盘 onChanged:(value) { setState(() { fieldPointX = double.tryParse(value) ?? fieldPointX; }); }, decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'X' ), ),
效果说明
- 输入过程中不会再触发
FormatException,无效的中间输入(如单独的-或.)会被tryParse忽略,保留原有值 - 用户无法输入
3.3.3、3-、--3这类无效格式 - 自动补全开头小数点的0,提升输入体验
内容的提问来源于stack exchange,提问作者Tan K
相关产品推荐
相关产品推荐

