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

Flutter TextFormField数字键盘输入非数字字符触发空白页异常

问题诱因
  • keyboardType: TextInputType.number 仅负责调起数字布局的软键盘,本身不具备任何输入内容拦截能力,不能作为输入合法性的保障。
  • 原生FilteringTextInputFormatter.digitsOnly存在跨平台兼容缺陷:在部分安卓定制系统、第三方输入法、低版本Flutter框架场景下,无法完全拦截-、,、.、零宽空格这类非数字字符,符号会绕过过滤直接写入输入框控制器。
  • 校验逻辑存在未捕获的异常风险:
    1. 代码中使用value!做强制非空断言,极端场景下输入值为null时会直接触发空指针异常
    2. 当特殊字符绕过过滤进入输入值、或输入为空字符串时,分支中直接调用int.parse(value)解析非法字符串,会触发未捕获的FormatException,导致页面崩溃渲染空白页,根本无法走到返回校验错误提示的逻辑。
修复方案

从输入拦截、校验逻辑两个层面做加固,彻底规避异常:

  • 替换兼容性差的digitsOnly过滤器,使用严格正则白名单仅允许0-9的纯数字输入,从源头阻断非数字字符写入
  • 新增输入长度限制,由于有效值范围是1-30,最多允许输入2位数字,减少无效输入
  • 重写校验逻辑,移除强制非空断言,所有字符串转数字操作统一用不会抛出异常的tryParse方法,所有非法场景统一返回校验提示

修复后的完整实现代码:

if (isPraticeChecked)
  TextFormField(
    decoration: const InputDecoration(labelText: 'No.of Questions'),
    controller: noOfquestionController,
    keyboardType: TextInputType.number,
    inputFormatters: [
      // 严格白名单,仅允许输入0-9纯数字
      FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
      // 限制最大输入长度为2位,匹配1-30的取值范围
      LengthLimitingTextInputFormatter(2),
    ],
    validator: (value) {
      // 空值校验,不使用强制非空断言
      if (value == null || value.isEmpty) {
        return 'No. of question must be 1 to 30.';
      }
      // 安全解析,不会触发格式异常
      final questionCount = int.tryParse(value);
      if (questionCount == null || questionCount < 1 || questionCount > 30) {
        return 'No. of question must be 1 to 30.';
      }
      return null;
    },
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:15:39