我想禁用一个按钮,直到文本表单字段有效。然后,一旦数据有效,按钮应该被启用。我收到了关于SO的帮助以前有一个类似的问题,但似乎不能应用我学到的这个问题。数据是有效的,当用户添加超过3个字符,少于20。我创建了一个bool(_isValidated),并在用户输入有效数据后将其添加到调用setState的validateerName方法中,但这肯定是错误的,并生成错误消息。错误消息是:
在构建过程中调用setState()或markNeedsBuild()。
我不知道我做错了什么。任何帮助都将不胜感激。谢谢。
class CreateUserNamePage extends StatefulWidget {
const CreateUserNamePage({
Key? key,
}) : super(key: key);
@override
_CreateUserNamePageState createState() => _CreateUserNamePageState();
}
class _CreateUserNamePageState extends State<CreateUserNamePage> {
final _formKey = GlobalKey<FormState>();
bool _isValidated = false;
late String userName;
final TextEditingController _userNameController = TextEditingController();
@override
void initState() {
super.initState();
_userNameController.addListener(() {
setState(() {});
});
}
void _clearUserNameTextField() {
setState(() {
_userNameController.clear();
});
}
String? _validateUserName(value) {
if (value!.isEmpty) {
return ValidatorString.userNameRequired;
} else if (value.trim().length < 3) {
return ValidatorString.userNameTooShort;
} else if (value.trim().length > 20) {
return ValidatorString.userNameTooLong;
} else {
setState(() {
_isValidated = true;
});
return null;
}
}
void _createNewUserName() {
final form = _formKey.currentState;
if (form!.validate()) {
form.save();
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Welcome $userName'),
),
);
Timer(const Duration(seconds: 2), () {
Navigator.pop(context, userName);
});
}
@override
void dispose() {
_userNameController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final isPortrait =
MediaQuery.of(context).orientation == Orientation.portrait;
final screenHeight = MediaQuery.of(context).size.height;
return WillPopScope(
onWillPop: () async => false,
child: Scaffold(
appBar: CreateUserNameAppBar(
preferredAppBarSize:
isPortrait ? screenHeight / 15.07 : screenHeight / 6.96,
),
body: ListView(
children: [
Column(
children: [
const CreateUserNamePageHeading(),
CreateUserNameTextFieldTwo(
userNameController: _userNameController,
createUserFormKey: _formKey,
onSaved: (value) => userName = value as String,
suffixIcon: _userNameController.text.isEmpty
? const EmptyContainer()
: ClearTextFieldIconButton(
onPressed: _clearUserNameTextField,
),
validator: _validateUserName,
),
CreateUserNameButton(
buttonText: ButtonString.createUserName,
onPressed: _isValidated ? _createNewUserName : null,
),
],
),
],
),
),
);
}
}
字符串
4条答案
按热度按时间wyyhbhjk1#
只需使用表单验证,在
TextFormField
编辑验证器函数中,添加onChange函数并调用setState
以获取inputtedValue,该值也可以保留禁用按钮,除非表单经过验证。需要注意的要点:
1.使用
final _formKey = GlobalKey<FormState>();
1.其中
String? inputtedValue;
和!userInteracts()
是窍门,可以参考代码;1.当ElevatedButton onPressed方法为null时,按钮将被禁用。只需传入条件
!userInteracts() || _formKey.currentState == null || !_formKey.currentState!.validate()
验证码:
字符串
cnjp1d6j2#
我认为更好的方法是为按钮的onPressed参数分配空值。请查看下面的链接。https://www.flutterbeads.com/disable-button-in-flutter/
iovurdzv3#
你有自定义的小部件,所以我不知道你的小部件是如何工作的,但在这里你可以使用AbsorbPointer禁用一个按钮,并检查你的textformfield文本在onChange参数像这里;
字符串
0lvr5msh4#
禁用按钮的方法总是将null传递给onPressed回调,您可以使用按钮主题来设置这些样式。
字符串
更好的方法是在流中的某个地方保存一个布尔值并更新它