我遇到了同样的问题this question on SO,我通过遵循提供的建议解决了问题(我在setState()
中称onChanged
)...问题是我的情况是{如果该字段在视图中不可见(如果您滚动视图直到不再显示该视图),则不会调用{1}}函数,因此我可以以无效状态提交表单。
我应该如何触发validator
中当前未显示的字段的验证?
更新:
以下是该问题的简单演示(我正在使用它在一个隔离的简单应用中进行调试):
ListView
答案 0 :(得分:0)
我可以想到两种方法 1)您不能使用验证器。使用提供者的验证方法。如果提供者发回错误,请显示小吃店。 2)您可以使用验证器。您还必须在提供程序中使用验证方法。如果provider返回错误,请使用scrollcontroller滚动到所需的列表元素,并希望届时将激活表单字段验证器。
答案 1 :(得分:0)
解决方案很简单,只是不使用ListView
而是依靠SingleChildScrollView
(并将表单本身作为子元素传递)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyForm extends StatefulWidget {
@override
State createState() {
return _MyFormState();
}
}
class _MyFormState extends State<MyForm> {
static final GlobalKey<FormState> _formKey = GlobalKey();
final Map<int, String> model = Map<int, String>();
@override
void initState() {
print('initState()');
for (int i = 0; i < 20; i++) {
model[i] = null;
}
super.initState();
}
String validate(String value) {
return value.isEmpty ? 'Cannot be blank!' : null;
}
void submitForm() {
final FormState formState = _formKey.currentState;
if (formState.validate()) {
print('form is valid');
formState.save();
} else {
print('form is invalid');
}
}
@override
Widget build(BuildContext context) {
List<Widget> fields = [];
for (int i = 0; i < 20; i++) {
Widget widget = TextFormField(
initialValue: model[i],
decoration: InputDecoration(
labelText: 'field $i',
),
validator: validate,
onFieldSubmitted: (String value) {
print('field $i onFieldSubmitted()');
setState(() {
model[i] = value;
});
},
);
fields.add(widget);
}
fields.add(RaisedButton(
child: Text('save'),
onPressed: submitForm,
));
return SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: fields,
),
),
);
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('form test'),
),
body: MyForm(),
),
);
}
}