Flutter中_formKey.currentState始终为null的问题求助
问题:Form的GlobalKey.currentState始终为null
在Form组件内部放置了AnimatedLoadingButton,并传入更新数据的回调函数。验证表单合法性时,无论何种情况,_formKey.currentState均为null。当前组件内存在两个Form,不确定是否因此引发问题。
相关代码实现
组件状态类代码
class _CustomerProfileAccountFormState extends State<CustomerProfileAccountForm> { final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _paswordFormKey = GlobalKey<FormState>(); Widget build(BuildContext context) { final delegate = S.of(context); const EdgeInsets verticalSpaceBetweenFields = EdgeInsets.all(8.0); return FutureBuilder( future: _userProfile, builder: (context, AsyncSnapshot<UserProfile> snapshot) { if (snapshot.hasData) { return Column(children: [ Form( child: Padding( padding: const EdgeInsets.all(6), key: _formKey, child: Column(children: <Widget>[ Text( delegate.your_account, style: Theme.of(context).textTheme.headlineMedium, ), Padding( padding: verticalSpaceBetweenFields, child: TextFormField( controller: _formControllers['displayName'], key: _displayNameKey, style: TextinputStyles.standardStyle(context), validator: (value) => Validators.maxLengthValidator( value, displayNameMaxLength), decoration: TextinputStyles.profileInputDecoration(context) .copyWith(labelText: delegate.displayName), ), ), Padding( padding: verticalSpaceBetweenFields, child: AnimatedLoadingButton( onPressed: _updateUserProfile, initText: delegate.update_profile, doneText: delegate.updated, loadingText: delegate.updating, errorText: delegate.error, buttonState: buttonState, )), ]), ), ), Form( child: Padding( padding: const EdgeInsets.all(6), key: _paswordFormKey, child: Column(children: <Widget>[...
表单检查函数代码
void _updateUserProfile() async { try { if (_formKey.currentState!.validate()) { setState(() { buttonState = ButtonLoadingState.loading; }); Map<String, dynamic> data = { "displayName": _formControllers['displayName']?.text }; await userProfileVM.updateProfile(widget.uid, data); setState(() { buttonState = ButtonLoadingState.done; }); } } catch (error) { setState(() { buttonState = ButtonLoadingState.error; }); globals.scaffoldMessengerKey.currentState! .showSnackBar(SnackbarsHelper.showSnackbarError(error.toString())); debugPrint('Error al obtener usuario: $error'); rethrow; } }
解决方案
问题出在GlobalKey的绑定位置错误:你把_formKey和_paswordFormKey绑定到了Padding组件上,而不是对应的Form组件上。Flutter需要通过GlobalKey关联到Form组件才能获取其FormState实例,绑定到子组件自然无法拿到FormState。
修正后的代码
将两个Form的GlobalKey移到Form组件的参数中:
// 第一个Form修正 Form( key: _formKey, // 把key移到Form组件上 child: Padding( padding: const EdgeInsets.all(6), child: Column(children: <Widget>[ // ... 原有内容保持不变 ]), ), ), // 第二个Form修正 Form( key: _paswordFormKey, // 同样移到Form组件上 child: Padding( padding: const EdgeInsets.all(6), child: Column(children: <Widget>[...
补充说明
组件内存在多个Form本身不会引发问题,只要每个Form都绑定独立的GlobalKey即可。修正后调用_formKey.currentState!.validate()就能正常获取FormState并执行表单验证。
内容的提问来源于stack exchange,提问作者Rafael Osuna Dominguez
相关产品推荐
相关产品推荐

