Flutter Enable/Disable 基于TextFormField内容的按钮
Flutter Enable/Disable Button based on TextFormField content
如何 activate/deactivate 基于 TextFormField 内容的按钮?
我想确保用户只有在 TextFormField 中输入了 10 个数字(如果是手机号码)时才能按下按钮 X。
谢谢!
一个简单的方法是将我们的 TextFormField 的自动验证 属性 设置为 true
。这将自动检测我们的 TextFormField 小部件上的更改。然后我们可以尝试在验证器 属性 上检查我们的 TextFormField 的值是否具有 10 个字符的字符串长度。之后我们可以调用 setState 来启用或禁用我们的按钮(我在这个例子中使用 FlatButton)。
bool _btnEnabled = false;
...
@override
Widget build(BuildContext context){
...
TextFormField(
...
autovalidate: true,
validator: (String txt){
if (txt.length == 10){
setState((){
_btnEnabled = true;
});
} else {
setState((){
_btnEnabled = false;
});
}
}
...
FlatButton(
onPressed: _btnEnabled == true ? yourCallback : null,
child: ...
接受的答案似乎无法使用最新的 Flutter v1.7.8(稳定),它给我以下错误:
无法将此 TestForm 小部件标记为需要构建,因为框架已经在构建小部件的过程中
工作版本如下所示:
...
autovalidate: true,
validator: (String txt){
bool isValid = txt.length == 10;
if (isValid != _btnEnabled) {
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_btnEnabled = txt.length == 10;
});
});
}
}
...
小部件的状态可以在表单的 onChanged 回调中更新,只要任何表单字段的值发生变化,回调就会被调用。在那里您可以使用表单键来验证表单并将标志设置为 enable/disable 按钮。此解决方案允许您缩放以禁用具有多个字段的表单中的按钮。例如,
/// Key used to reference the form.
final _formKey = GlobalKey<FormState>();
...
Form(
key: _formKey,
onChanged: () => setState(() => _enableBtn = _formKey.currentState.validate()),
child: ListView(
children: <Widget>[
TextFormField(
validator: (value) => value.length < 10 ?
'Number must be at least 10 digits' : // return an error message
null,
...
),
],
),
)
...
FlatButton(
onPressed: _enableBtn ?
() => _doSomething() :
null, // setting onPressed to null disables the button.
...
出现错误 "setState() or markNeedsBuild() called during build.",答案已被接受。只需添加 Future.delayed(Duration.zero).then(....) 作为技巧解决方案,它在 flutter 1.12.13
上运行
TextFormField(
...
autovalidate: true,
validator: (String txt){
if (txt.length == 10){
Future.delayed(Duration.zero).then((_){
setState((){
_btnEnabled = true;
});
});
} else {
Future.delayed(Duration.zero).then((_){
setState((){
_btnEnabled = false;
});
});
}
}
....
你可以使用 Flutter Reactive Forms。这是一种处理表单输入和验证的模型驱动方法,深受 Angular 的 Reactive Forms 的启发。
使用 libray 非常简单,在文档中有一个部分解释了如何 Enable/Disable 根据整个表单的有效性提交按钮,而不仅仅是一个字段。
你可以使用这个方法。
bool isEnable = false;
void validateButton() {
bool isValid = true;
isValid = userEmail.isNotEmpty &&
userPassword.isNotEmpty &&
validateEmail(userEmail) &&
userPassword.length >= 8;
setState(() {
isEnable = isValid;
});
}
现在在您的文本字段 onChanged 方法中,您必须调用此函数
像这样
onChanged: (email) {
userEmail = email;
setState(() {});
validateButton();
},
并在您的登录按钮中
isEnable?ActiveButton():DisableButton()
如何 activate/deactivate 基于 TextFormField 内容的按钮?
我想确保用户只有在 TextFormField 中输入了 10 个数字(如果是手机号码)时才能按下按钮 X。
谢谢!
一个简单的方法是将我们的 TextFormField 的自动验证 属性 设置为 true
。这将自动检测我们的 TextFormField 小部件上的更改。然后我们可以尝试在验证器 属性 上检查我们的 TextFormField 的值是否具有 10 个字符的字符串长度。之后我们可以调用 setState 来启用或禁用我们的按钮(我在这个例子中使用 FlatButton)。
bool _btnEnabled = false;
...
@override
Widget build(BuildContext context){
...
TextFormField(
...
autovalidate: true,
validator: (String txt){
if (txt.length == 10){
setState((){
_btnEnabled = true;
});
} else {
setState((){
_btnEnabled = false;
});
}
}
...
FlatButton(
onPressed: _btnEnabled == true ? yourCallback : null,
child: ...
接受的答案似乎无法使用最新的 Flutter v1.7.8(稳定),它给我以下错误:
无法将此 TestForm 小部件标记为需要构建,因为框架已经在构建小部件的过程中
工作版本如下所示:
...
autovalidate: true,
validator: (String txt){
bool isValid = txt.length == 10;
if (isValid != _btnEnabled) {
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_btnEnabled = txt.length == 10;
});
});
}
}
...
小部件的状态可以在表单的 onChanged 回调中更新,只要任何表单字段的值发生变化,回调就会被调用。在那里您可以使用表单键来验证表单并将标志设置为 enable/disable 按钮。此解决方案允许您缩放以禁用具有多个字段的表单中的按钮。例如,
/// Key used to reference the form.
final _formKey = GlobalKey<FormState>();
...
Form(
key: _formKey,
onChanged: () => setState(() => _enableBtn = _formKey.currentState.validate()),
child: ListView(
children: <Widget>[
TextFormField(
validator: (value) => value.length < 10 ?
'Number must be at least 10 digits' : // return an error message
null,
...
),
],
),
)
...
FlatButton(
onPressed: _enableBtn ?
() => _doSomething() :
null, // setting onPressed to null disables the button.
...
出现错误 "setState() or markNeedsBuild() called during build.",答案已被接受。只需添加 Future.delayed(Duration.zero).then(....) 作为技巧解决方案,它在 flutter 1.12.13
上运行TextFormField(
...
autovalidate: true,
validator: (String txt){
if (txt.length == 10){
Future.delayed(Duration.zero).then((_){
setState((){
_btnEnabled = true;
});
});
} else {
Future.delayed(Duration.zero).then((_){
setState((){
_btnEnabled = false;
});
});
}
}
....
你可以使用 Flutter Reactive Forms。这是一种处理表单输入和验证的模型驱动方法,深受 Angular 的 Reactive Forms 的启发。
使用 libray 非常简单,在文档中有一个部分解释了如何 Enable/Disable 根据整个表单的有效性提交按钮,而不仅仅是一个字段。
你可以使用这个方法。
bool isEnable = false;
void validateButton() {
bool isValid = true;
isValid = userEmail.isNotEmpty &&
userPassword.isNotEmpty &&
validateEmail(userEmail) &&
userPassword.length >= 8;
setState(() {
isEnable = isValid;
});
}
现在在您的文本字段 onChanged 方法中,您必须调用此函数
像这样
onChanged: (email) {
userEmail = email;
setState(() {});
validateButton();
},
并在您的登录按钮中
isEnable?ActiveButton():DisableButton()