如何在文本表单字段具有有效数据 Flutter 之前禁用按钮
How to disable button until text form field has valid data Flutter
我想做的是在文本表单字段有效之前禁用提升按钮。然后一旦数据有效,应该启用提升按钮。我已经查看了几个 SO 线程和关于 Google 的几篇文章,内容涉及如何在验证文本表单字段之前禁用按钮。他们都关注文本表单字段是否为空,这不是我在这里要问的。我正在使用正则表达式来确定用户是否输入了有效的电子邮件地址。只有当输入的数据是有效的电子邮件时,数据才被视为有效。那是我希望按钮启用的时候。如果我尝试在 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'),
),
],
);
}
}
大多数小部件的启用和禁用功能是相同的
设置onPressed
属性如下图
onPressed : null
returns 一个禁用的小部件,同时
onPressed: (){}
或 onPressed: _functionName
returns 已启用小部件
在这种情况下,它将是这样的:
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
Auth().resetPassword(
context,
_emailController.text.trim(),
);
} else {
print('disabled');
}
},
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,则按钮被禁用。
首先,将逻辑移动到命名函数中
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?),它将带您走向空异常**
我想做的是在文本表单字段有效之前禁用提升按钮。然后一旦数据有效,应该启用提升按钮。我已经查看了几个 SO 线程和关于 Google 的几篇文章,内容涉及如何在验证文本表单字段之前禁用按钮。他们都关注文本表单字段是否为空,这不是我在这里要问的。我正在使用正则表达式来确定用户是否输入了有效的电子邮件地址。只有当输入的数据是有效的电子邮件时,数据才被视为有效。那是我希望按钮启用的时候。如果我尝试在 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'),
),
],
);
}
}
大多数小部件的启用和禁用功能是相同的
设置onPressed
属性如下图
onPressed : null
returns 一个禁用的小部件,同时
onPressed: (){}
或 onPressed: _functionName
returns 已启用小部件
在这种情况下,它将是这样的:
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
Auth().resetPassword(
context,
_emailController.text.trim(),
);
} else {
print('disabled');
}
},
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,则按钮被禁用。
首先,将逻辑移动到命名函数中
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?),它将带您走向空异常**