DropdownButtonFormField设置AutovalidateMode.always校验不生效怎么办
问题根因
校验逻辑不生效核心是1个关键写法错误,附带1个类型隐患:
- 核心错误:
GlobalKey<FormState>()被直接写在了build方法内部。每次setState触发组件重建时,都会生成一个全新的GlobalKey实例,Form组件会因为key变化直接销毁旧状态、重新初始化,validator的校验状态、触发逻辑完全无法正常留存,自然不会按预期展示错误提示。 - 类型隐患:通过
e['unit']从Map中取出的值是Object?动态类型,虽然你给DropdownMenuItem指定了String泛型,但没有做显式类型转换,极端场景下会出现值类型不匹配,导致value == '1'的比对逻辑失效。
修复后可运行代码
class ValidateDropdownButton extends StatefulWidget { State<ValidateDropdownButton> createState() => _ValidateDropdownButtonState(); } class _ValidateDropdownButtonState extends State<ValidateDropdownButton> { // 将Form的key提升为State成员变量,保证重建时状态不丢失 final _formKey = GlobalKey<FormState>(); var data = [ {'unit': '1', 'project': 'a'}, {'unit': '1', 'project': 'b'}, {'unit': '2', 'project': 'c'}, {'unit': '2', 'project': 'd'}, ]; String? unit; Widget build(BuildContext context) { return Scaffold( body: Form( key: _formKey, autovalidateMode: AutovalidateMode.always, child: Column( children: [ DropdownButtonFormField<String>( value: unit, items: data .map((e) => e['unit'] as String) // 显式做类型转换 .toSet() .map((e) => DropdownMenuItem<String>(value: e, child: Text(e))) .toList(), onChanged: (String? value) => setState(() => unit = value), validator: (value) { if (value == '1') return 'error'; return null; }, ), ], ), ), ); } }
修改说明
- 把Form对应的GlobalKey从build方法移到State类的成员属性位置,组件触发setState重建时,Form持有的状态不会被重置,validator可以正常响应值变化触发校验
- 给
DropdownButtonFormField显式声明<String>泛型,对Map中取出的unit值做显式类型转换,避免动态类型导致的值比对异常 - 原本写的validator判断逻辑本身没有问题,修复上述两个问题后,选中值为'1'时就会正常展示"error"错误提示
内容的提问来源于stack exchange,提问作者José Luis Zarabanda Díaz
相关产品推荐
相关产品推荐

