Flutter TextFormField数字键盘输入非数字字符触发空白页异常
问题诱因
keyboardType: TextInputType.number仅负责调起数字布局的软键盘,本身不具备任何输入内容拦截能力,不能作为输入合法性的保障。- 原生
FilteringTextInputFormatter.digitsOnly存在跨平台兼容缺陷:在部分安卓定制系统、第三方输入法、低版本Flutter框架场景下,无法完全拦截-、,、.、零宽空格这类非数字字符,符号会绕过过滤直接写入输入框控制器。 - 校验逻辑存在未捕获的异常风险:
- 代码中使用
value!做强制非空断言,极端场景下输入值为null时会直接触发空指针异常 - 当特殊字符绕过过滤进入输入值、或输入为空字符串时,分支中直接调用
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
相关产品推荐
相关产品推荐

