Flutter如何实现TextField输入时隐藏错误提示边框及高效表单校验
Flutter TextField 多字段校验高效实现方案
你可以通过以下两种方案彻底避免为每个输入框单独声明bool变量的问题:
方案1:使用Flutter原生Form组件自带的校验能力(最推荐)
Flutter的TextFormField本身就内置了validator校验属性,搭配外层的Form组件可以自动管理所有字段的校验状态,无需手动维护校验变量:
第一步:修改自定义组件,新增validator参数、移除errortext和onChanged的强制传参
Widget textformfieldCustom( BuildContext context, TextInputType keyboardType, double width, Widget icon, TextEditingController controller, String? Function(String?)? validator, // 新增校验回调 String hintText, String labelText, { void Function(String)? onChanged, // 可选参数,有额外逻辑时再传 }) { return Container( width: width, child: TextFormField( keyboardType: keyboardType, decoration: InputDecoration( contentPadding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 10.0), labelText: labelText, labelStyle: GoogleFonts.montserrat(color: HexColor("#6e6b7b")), hintStyle: GoogleFonts.montserrat(), hintText: hintText, prefixIcon: icon, focusedBorder: OutlineInputBorder( borderRadius: const BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: HexColor("#6610f2")), ), border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), ), errorBorder: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: Colors.red, width: 1), ), ), onSaved: (String? value) {}, onChanged: onChanged, controller: controller, validator: validator, // 绑定校验逻辑 autovalidateMode: AutovalidateMode.onUserInteraction, // 输入时自动触发校验 ), ); }
第二步:外层包裹Form组件调用
// 先声明Form的全局key final _formKey = GlobalKey<FormState>(); // 页面布局里包裹Form Form( key: _formKey, child: Column( children: [ // 手机号输入框 textformfieldCustom( context, TextInputType.number, MediaQuery.of(context).size.width * 0.9, Icon(Icons.phone, color: iconColor), phoneNoController, // 直接写校验逻辑,返回错误提示或者null (value) => value?.isEmpty == true ? 'This is the required field' : null, 'Enter your phone number', 'Phone number', ), // 第二个输入框,直接加就行,不用额外声明bool变量 textformfieldCustom( context, TextInputType.emailAddress, MediaQuery.of(context).size.width * 0.9, Icon(Icons.email, color: iconColor), emailController, (value) { if (value?.isEmpty == true) return '邮箱不能为空'; if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value!)) return '邮箱格式不正确'; return null; }, 'Enter your email', 'Email', ), // 提交按钮可以统一校验所有字段 ElevatedButton( onPressed: () { if (_formKey.currentState?.validate() == true) { // 所有字段校验通过,执行提交逻辑 } }, child: const Text('提交'), ) ], ), )
这个方案的优势:
- 无需维护任何校验相关的状态变量,多少个输入框都只需要一个Form的全局key
- 内置自动触发校验的规则,
AutovalidateMode.onUserInteraction就是用户输入后自动校验,完全符合你输入内容自动隐藏错误、留空显示错误的需求 - 提交时可以一键校验所有字段是否合法
方案2:如果不想用Form组件,用Map统一管理校验状态
如果你的场景不需要统一提交校验,也可以用一个Map来存储所有字段的校验状态,不用单独声明多个bool变量:
// 只需要声明一个Map final Map<String, bool> _validateMap = {}; // 调用组件的时候用字段名当key textformfieldCustom( context, TextInputType.number, MediaQuery.of(context).size.width * 0.9, Icon(Icons.email,color: iconColor,), phoneNoController, _validateMap['phone'] == true ? 'This is the required field' : null, (value) { setState(() { _validateMap['phone'] = phoneNoController.text.isEmpty; }); }, 'Enter your phone number', 'Phone number' ),
这种方式10个输入框只需要维护一个Map就足够,也不需要单独声明10个bool变量。
内容的提问来源于stack exchange,提问作者TimeToCode
相关产品推荐
相关产品推荐

