我在这个问题上也遇到了同样的问题,我通过遵循提供的建议解决了(我setState()在 中调用onChanged)...问题是,在我的情况下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(),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
解决方案很简单,只是不使用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(),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2981 次 |
| 最近记录: |