You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 04:20:22