【发布时间】:2019-05-26 14:45:25
【问题描述】:
如何根据 TextFormField 的内容激活/停用按钮?
如果 TextFormField 输入了 10 个数字(如果它是手机号码),我想确保用户只能按下按钮 X。
谢谢!
【问题讨论】:
标签: button keyboard flutter textfield flutter-layout
如何根据 TextFormField 的内容激活/停用按钮?
如果 TextFormField 输入了 10 个数字(如果它是手机号码),我想确保用户只能按下按钮 X。
谢谢!
【问题讨论】:
标签: button keyboard flutter textfield flutter-layout
一种简单的方法是将 TextFormField 的 autovalidate 属性设置为 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 回调中更新,只要任何表单字段的值发生更改,就会调用该回调。在那里,您可以使用表单键来验证表单并设置标志以启用/禁用按钮。此解决方案允许您缩放以禁用具有多个字段的表单中的按钮。例如,
/// 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() 或 markNeedsBuild()。”接受的答案。只需添加 Future.delayed(Duration.zero).then(....) 作为一个技巧解决方案,它正在处理颤振 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 的反应式表单的启发。
使用 libray 非常简单,文档中有一节解释了如何根据整个表单的有效性启用/禁用提交按钮,而不仅仅是一个字段。
【讨论】:
你可以使用这个方法。
bool isEnable = false;
void validateButton() {
bool isValid = true;
isValid = userEmail.isNotEmpty &&
userPassword.isNotEmpty &&
validateEmail(userEmail) &&
userPassword.length >= 8;
setState(() {
isEnable = isValid;
});
}
现在在你的 Textfield onChanged 方法中你必须调用这个函数
喜欢这个
onChanged: (email) {
userEmail = email;
setState(() {});
validateButton();
},
在您的登录按钮中
isEnable?ActiveButton():DisableButton()
【讨论】: