如何禁用按钮,直到文本表单字段有有效的数据Flutter



我想做的是禁用提升按钮,直到文本表单字段有效。然后,一旦数据有效,就应该启用提升按钮。我在谷歌上查看了几个SO线程和一些关于如何在文本表单字段验证之前禁用按钮的文章。他们都关注文本表单字段是否为空,这不是我在这里所问的。我使用regex来确定用户是否输入了有效的电子邮件地址。只有当输入的数据是有效的电子邮件时,数据才被视为有效。这就是我希望按钮启用的时候。如果我试图在validateEmail方法中使用布尔值调用setState,我会得到错误:

在生成过程中调用了setState((或markNeedsBuild((。

任何帮助都将不胜感激。非常感谢。

class ResetPasswordForm extends StatefulWidget {
const ResetPasswordForm({Key? key}) : super(key: key);
@override
_ResetPasswordFormState createState() => _ResetPasswordFormState();
}
class _ResetPasswordFormState extends State<ResetPasswordForm> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _emailController = TextEditingController();
String? validateEmail(String? value) {
String pattern = ValidatorRegex.emailAddress;
RegExp regex = RegExp(pattern);
if (value == null || value.isEmpty || !regex.hasMatch(value)) {
return ValidatorString.enterValidEmail;
} else {
return null;
}
}
@override
void dispose() {
_emailController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Form(
key: _formKey,
child: TextFormField(
controller: _emailController,
validator: (value) => validateEmail(value),
),
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
Auth().resetPassword(
context,
_emailController.text.trim(),
);
}
},
child: const Text('Reset Password'),
),
],
);
}
}

你可以做这样的事情:

class ResetPasswordForm extends StatefulWidget {
const ResetPasswordForm({Key? key}) : super(key: key);
@override
_ResetPasswordFormState createState() => _ResetPasswordFormState();
}
class _ResetPasswordFormState extends State<ResetPasswordForm> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _emailController = TextEditingController();
final bool _isValidated = false;
String? validateEmail(String? value) {
String pattern = ValidatorRegex.emailAddress;
RegExp regex = RegExp(pattern);
if (value == null || value.isEmpty || !regex.hasMatch(value)) {
return ValidatorString.enterValidEmail;
} else {
setState(){
_isValidated = true;
}
return null;
}
}
@override
void dispose() {
_emailController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Form(
key: _formKey,
child: TextFormField(
controller: _emailController,
validator: (value) => validateEmail(value),
),
),
ElevatedButton(
onPressed:_isValidated
? () {
//do stuff
}
: null,,
child: const Text('Reset Password'),
),
],
);
}
}

如果onPressed为null,则该按钮被禁用。

启用和禁用大多数窗口小部件的功能相同

设置onPressed属性,如下所示

onPressed : nullonPressed: (){}onPressed: _functionName返回启用的窗口小部件

在这种情况下,它将是这样的:

ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
Auth().resetPassword(
context,
_emailController.text.trim(),
);
} else {
print('disabled');
}
},
child: const Text('Reset Password'),
),

首先,将逻辑移动到命名函数中

void _sendData (){
if (_formKey.currentState!.validate()) { 
Auth().resetPassword( context, 
_emailController.text.trim(), );
}

现在处于未压缩

onpressed: _emailController.text.trim.isNotEmpty?_sendData : null;

最好的方法是为这个创建一个表单密钥

final formGlobalKey = GlobalKey <FormState> ();

将其分配到类似的表单

Form(
key: formGlobalKey,

现在你只需要检查验证,比如:

ElevatedButton(
style: style,
onPressed: formGlobalKey.currentState==null?null: formGlobalKey.currentState!.validate()? () {
This is body of button} : null,
child: const Text('Enabled'),
),

**如果您没有使用第一个条件(formGlobalKey.currentState==null?(,它将导致null异常**

最新更新