我遇到了与这个问题相同的问题,并通过遵循提供的建议来解决(我在
onChanged
中调用setState()
)...问题是,在我的情况下,如果字段在视图中不可见(如果您滚动视图直到其不再显示),则validator
函数不会被调用,因此我可以以无效状态提交表单。
我该如何触发当前未显示在ListView
中的字段的验证?
更新:
以下是一个简单的演示问题的示例(我正在使用它来在隔离的简单应用程序中进行调试):
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<FormState>();
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;
});
},
onChanged: (String value) {
print('field $i onChanged()');
setState(() {
model[i] = value;
});
},
onSaved: (String value) {
print('field $i onSaved()');
setState(() {
model[i] = value;
});
},
);
fields.add(widget);
}
fields.add(RaisedButton(
child: Text('save'),
onPressed: submitForm,
));
return Form(
key: _formKey,
child: ListView(
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(),
),
);
}
}
FormState
的validate()
不会调用隐藏字段的验证器(换句话说,就像对表单的一部分进行验证而不是全部)。 - daveoncode