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

Flutter字符串负数字转double报错及输入限制问题

解决TextField输入double时的FormatException及多符号限制问题

问题根源

  • 当输入仅为-、.或-.时,double.parse()无法解析成有效数字,直接抛出FormatException
  • 原正则^-?\d*.?\d*允许输入多个-、.,还允许无数字的无效格式(比如单独的-)

解决方案

1. 严格限制输入格式(阻止多个-和.)

方法一:使用精准正则替换输入格式化器

用更严格的正则约束输入,只允许合法的数字格式:

FilteringTextInputFormatter.allow(RegExp(r'^-?\d*\.?\d+$|^-?\d+$|^-?\.$'))

这个正则允许的有效格式:

  • 正负整数(如123、-456)
  • 正负小数(如12.34、-56.78)
  • 单独的.或-.(方便后续补数字,同时杜绝多符号输入)

方法二:自定义InputFormatter(更灵活)

如果需要完全禁止单独的.或-,可以自定义格式化器实现更精细的控制:

class NumberInputFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
    String newText = newValue.text;
    
    // 负号只能在开头,且最多一个
    if (newText.contains('-') && newText.indexOf('-') != 0) {
      newText = newText.replaceAll('-', '');
    }
    
    // 小数点最多一个
    int dotCount = newText.split('.').length - 1;
    if (dotCount > 1) {
      int lastDotIndex = newText.lastIndexOf('.');
      newText = newText.substring(0, lastDotIndex) + newText.substring(lastDotIndex + 1);
    }
    
    return TextEditingValue(
      text: newText,
      selection: TextSelection.collapsed(offset: newText.length),
    );
  }
}

使用时替换原inputFormatters:

inputFormatters: [NumberInputFormatter()],

2. 安全解析double值(避免FormatException)

在onChanged回调中先判断输入有效性,再执行解析,避免无效输入触发报错:

onChanged:(value) {
  setState(() {
    // 处理空输入、仅符号的无效情况
    if (value.isEmpty || value == '-' || value == '.' || value == '-.') {
      data = 0.0; // 或设置为null,根据业务需求调整
      return;
    }
    // 安全解析,捕获异常兜底
    try {
      data = double.parse(value);
    } catch (e) {
      data = data ?? 0.0; // 保持原有值或设默认值
    }
  });
},

完整修改后的代码示例

TextFormField(
  inputFormatters: [NumberInputFormatter()],
  keyboardType: TextInputType.numberWithOptions(signed: true, decimal: true),
  onChanged:(value) {
    setState(() {
      if (value.isEmpty || value == '-' || value == '.' || value == '-.') {
        data = 0.0;
        return;
      }
      try {
        data = double.parse(value);
      } catch (e) {
        data = data ?? 0.0;
      }
    });
  },
  decoration: InputDecoration(
    border: OutlineInputBorder(),
    labelText: 'data'
  ),
)

内容的提问来源于stack exchange,提问作者Kimmy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:40:33