Flutter登录页表单验证错误提示不生效、点击后自动跳转问题
Flutter登录表单错误提示及校验跳转问题修复方案
存在的问题
removeError方法逻辑反向:当前判断条件为!errors.contains(error)时才执行移除,应该改为存在对应错误时才移除onChanged判断逻辑错误:使用else if分支,满足第一个条件后不会执行后续错误移除判断,需改为独立if判断- 校验规则错误:
- 密码校验误用邮箱正则表达式判断长度,应直接判断密码长度是否小于8位
- 邮箱校验通过后返回了非空的
value,不符合validator校验通过需返回null的规则 - 校验不通过时返回了空字符串,会导致输入框默认展示空的错误提示
- 跳转逻辑未做校验拦截:跳转代码未放在校验通过的判断分支内,导致无论是否校验通过都会触发跳转
- 错误列表未前置清空:每次触发校验前未清空历史错误,会导致错误重复累加残留
修复后的核心代码
登录表单代码
class sign_in_form extends StatefulWidget { const sign_in_form({Key? key}) : super(key: key); @override _sign_in_formState createState() => _sign_in_formState(); } class _sign_in_formState extends State<sign_in_form> { final _formKey = GlobalKey<FormState>(); String? email; String? password; final List<String?> errors = []; void addError ({String? error}) { if (!errors.contains(error)) { setState(() { errors.add(error); }); } } void removeError ({String? error}) { // 修复:错误存在时才移除 if (errors.contains(error)) { setState(() { errors.remove(error); }); } } @override Widget build(BuildContext context) { return Form( key: _formKey, child: Column( children: <Widget>[ buildEmailFormField(), SizedBox(height: getProportionateScreenHeight(20)), buildPasswordFormField(), SizedBox(height: getProportionateScreenHeight(20)), errors_form(errors: errors), SizedBox(height: getProportionateScreenHeight(20)), splash_button( press: () { // 修复:校验前先清空历史错误 setState(() { errors.clear(); }); if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); // 修复:跳转逻辑放在此处,校验通过才执行跳转 // 你的页面跳转代码写在这里 } }, ), ], ), ); } TextFormField buildEmailFormField() { return TextFormField( keyboardType: TextInputType.emailAddress, onSaved: (newValue) => email = newValue, onChanged: (value) { // 修复:改为独立if判断,避免分支拦截 if (value.isNotEmpty) { removeError(error: "Please Enter your email"); } if (emailValidatorRegExp.hasMatch(value)) { removeError(error: "Please Enter Valid Email"); } return; }, validator: (value) { if (value!.isEmpty) { addError(error: "Please Enter your email"); return null; } else if (!emailValidatorRegExp.hasMatch(value)) { addError(error: "Please Enter Valid Email"); return null; } // 修复:校验通过返回null return null; }, // 隐藏系统自带的错误提示,避免和自定义错误提示重复 decoration: const InputDecoration( labelText: "Email", hintText: "Enter your email", floatingLabelBehavior: FloatingLabelBehavior.always, suffixIcon: Padding( padding: EdgeInsets.fromLTRB(0, 20, 20, 20), child: Icon(Icons.email), ), errorStyle: TextStyle(height: 0), ), ); } TextFormField buildPasswordFormField() { return TextFormField( obscureText: true, onSaved: (newValue) => password = newValue, onChanged: (value){ // 修复:改为独立if判断 if (value.isNotEmpty) { removeError(error: "Please Enter your password"); } if (value.length >= 8) { removeError(error: "Password is too short"); } return; }, validator: (value){ if (value!.isEmpty) { addError(error: "Please Enter your password"); return null; } // 修复:改为判断密码长度,不再误用邮箱正则 else if (value.length < 8) { addError(error: "Password is too short"); return null; } return null; }, decoration: const InputDecoration( labelText: "Password", hintText: "Enter your password", floatingLabelBehavior: FloatingLabelBehavior.always, suffixIcon: Padding( padding: EdgeInsets.fromLTRB(0, 20, 20, 20), child: Icon(Icons.lock), ), errorStyle: TextStyle(height: 0), ), ); } }
错误提示表单代码无逻辑问题,可保持原样
class errors_form extends StatelessWidget { const errors_form({Key? key, required this.errors,}) : super(key: key); final List<String?> errors; @override Widget build(BuildContext context) { return Column( children: List.generate( errors.length, (index) => form_error_text(errors: errors[index]!)), ); } Row form_error_text ({required String errors}) { return Row( children: [ SvgPicture.asset( "assets/icons/Error.svg", height: getProportionateScreenWidth(14), width: getProportionateScreenWidth(14), ), SizedBox(width: getProportionateScreenWidth(14)), Text(errors), ], ); } }
内容的提问来源于stack exchange,提问作者Lyana
相关产品推荐
相关产品推荐

