我仍在学习Flutter,并为此挠头。我有一个包含3个字段的表格(电子邮件,密码和password_confirmation)。我正在使用验证器,并更新用作按钮启用状态的条件的变量。问题是,例如,我更改电子邮件时,按钮启用状态没有更新。如果我热重启,它将更新按钮状态。如何强制按钮重新评估其状况?Flutter这样做的方式是什么?谢谢
bool _validEmail = false;
bool _validPassword = false;
bool _validPasswordConfirmation = false;
bool _validAccount = false;
SignUpError _serverSignUpErrors = null;
Form signup_form() {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//Email field
Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Email",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
SizedBox(
height: 10,
),
TextFormField(
controller: _emailFieldController,
obscureText: false,
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Color(0xfff3f3f4),
filled: true),
onChanged: (String value) {
if(_serverSignUpErrors?.email_errors?.isNotEmpty == true)
_serverSignUpErrors.email_errors.clear();
},
autovalidate: true,
validator: (value) {
_validEmail = false;
if (value.isEmpty)
return 'Please enter some text';
//Validate email
String p = r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regExp = new RegExp(p);
if(!regExp.hasMatch(value))
return 'Invalid email';
if(_serverSignUpErrors?.email_errors?.isNotEmpty == true)
return _serverSignUpErrors.email_errors.join(';');
_validEmail = true;
return null;
}
)
],
),
),
//Password field
Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Password",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
SizedBox(
height: 10,
),
TextFormField(
controller: _passwordController,
obscureText: true,
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Color(0xfff3f3f4),
filled: true),
onChanged: (String value) {
if(_serverSignUpErrors?.password_errors?.isNotEmpty == true)
_serverSignUpErrors.password_errors.clear();
this.didChangeDependencies();
},
autovalidate: true,
validator: (value) {
_validPassword = false;
if (value.isEmpty || value.length < 4)
return 'Password must be at least 6 chars wide';
if(_serverSignUpErrors?.password_errors?.isNotEmpty == true)
return _serverSignUpErrors.password_errors.join(';');
_validPassword = true;
return null;
}
)
],
),
),
//Password field
Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Password confirmation",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
SizedBox(
height: 10,
),
TextFormField(
controller: _passwordConfirmationController,
obscureText: true,
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Color(0xfff3f3f4),
filled: true),
onChanged: (String value) {
if(_serverSignUpErrors?.password_confirmation_errors?.isNotEmpty == true)
_serverSignUpErrors.password_confirmation_errors.clear();
this.didChangeDependencies();
},
autovalidate: true,
validator: (value) {
_validPasswordConfirmation = false;
if (value.isEmpty)
return 'Please enter password confirmation';
if(value != _passwordController.text)
return 'Password confirmation doesn\'t match password';
if(_serverSignUpErrors?.password_confirmation_errors?.isNotEmpty == true)
return _serverSignUpErrors.password_confirmation_errors.join(';');
_validPasswordConfirmation = true;
return null;
}
)
],
),
),
Center(
child: FlatButton(
onPressed: (_validEmail && _validPassword && _validPasswordConfirmation && _validAccount == false) ? () async => await onRegister() : null,
disabledColor: Colors.blueGrey,
child: Text(
'Register Now',
style: TextStyle(fontSize: 20, color: Colors.white),
),
color: Colors.blue, //specify background color for the button here
colorBrightness: Brightness.dark, //specify the color brightness here, either `Brightness.dark` for darl and `Brightness.light` for light
highlightColor: Colors.red, //color when the button is being actively pressed, quickly fills the button and fades out after
padding: EdgeInsets.symmetric(horizontal: 8.0, vertical: 5.0), // gives padding to the button
),
),
]
)
);
}
[看来您是== false
正在颠倒您的预期行为。不确定这是否是您想要的。
onPressed: (_validEmail && _validPassword && _validPasswordConfirmation && _validAccount == false) ? () async => await onRegister() : null,
为了解决您的错误,您应该使用_validEmail
,_validPassword
等变量来包装要更改状态的所有内容。当您更改状态时,这将重新构建窗口小部件(包括按钮),以便在需要时启用它,并且您将获得想要的行为。