如何找到调用formKey.currentState后出错的第一个TextFormField?validate()



我在CustomScrollView()中的Form()小部件中有一个TextFormField()小部件列表。当我调用表单的validate()方法时,所有字段都得到了正确验证。然而,由于有很多字段,第一个(可能也是唯一一个(实际出错的字段可能不在视野中。因此表单不会提交,但是用户需要手动滚动以查找错误。

如何使scrollView滚动到错误的第一个字段?

我知道我可以为表单字段设置一个FocusNode,然后发出requestFocus()scrollView将滚动到该字段-这就是我想要的,但是,我无法确定哪个字段实际上出错了?

有人知道什么是实现我的目标的最佳方法吗?对于scrollView中的Form,滚动到错误的第一个TestFormField

我创建了一个示例,它可能是您的解决方案,并根据您的需求进行调整:

class _TestState extends State<Test> {
final _controllerUsername = TextEditingController();
final _controllerPassword = TextEditingController();
final _controllerEmail = TextEditingController();
final _controllerAddress = TextEditingController();
final _focusAddress = FocusNode();
final _focusUsername = FocusNode();
final _focusPassword = FocusNode();
final _focusEmail = FocusNode();
int? errorIndex;
final _formKey = GlobalKey<FormState>();
late List<FocusNode> focusNodes = [
_focusUsername,
_focusPassword,
_focusEmail,
_focusAddress,
];
void validateForm() {
if (_formKey.currentState!.validate()) {
errorIndex = null;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
} else {
print("error occured at $errorIndex form field");
focusNodes[errorIndex!].requestFocus();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(hintText: 'username'),
textInputAction: TextInputAction.next,
controller: _controllerUsername,
focusNode: _focusUsername,
validator: (value) {
var validation = value?.isNotEmpty ?? true;
errorIndex = validation ? null : 0;
return validation ? null : "Input your username";
},
),
TextFormField(
decoration: InputDecoration(hintText: 'password'),
textInputAction: TextInputAction.next,
controller: _controllerPassword,
focusNode: _focusPassword,
validator: (value) {
var validation = value?.isNotEmpty ?? true;
errorIndex = validation ? errorIndex : errorIndex ?? 1;
return validation ? null : "Input your password";
},
),
TextFormField(
decoration: InputDecoration(hintText: 'email'),
textInputAction: TextInputAction.next,
controller: _controllerEmail,
focusNode: _focusEmail,
validator: (value) {
var validation = value?.isNotEmpty ?? true;
errorIndex = validation ? errorIndex : errorIndex ?? 2;
return validation ? null : "Input your email";
},
),
TextFormField(
decoration: InputDecoration(hintText: 'address'),
textInputAction: TextInputAction.done,
controller: _controllerAddress,
focusNode: _focusAddress,
validator: (value) {
var validation = value?.isNotEmpty ?? true;
errorIndex = validation ? errorIndex : errorIndex ?? 3;
return validation ? null : "Input your address";
},
),
ElevatedButton(onPressed: validateForm, child: Text('submit'))
],
),
),
),
);
}
}

最新更新