我有一个自定义的FormField MyFancyTextFormField,它只是将TextFormField包裹了一些附加功能。
我想单独使用此FormField,但我也想在另一个FormField中使用它:TextList基本上只是一列充满MyFancyTextFormFields的列。
我想到了这个
class FirstWidget extends StatefulWidget {
@override
State createState() => FirstWidgetState();
}
class FirstWidgetState extends State<FirstWidget> {
GlobalKey<FormState> _form = GlobalKey<FormState>();
List<String> initial = ['one', 'two', 'three'];
List<String> modified;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Form(
key: _form,
child: TextList(initialValue: initial, onSaved: (values) => print('TextList saved with: ${modified = values}')),
),
RaisedButton(
child: Text('Save'),
onPressed: () {
_form.currentState.save();
print('Initial value was: $initial, modified value is: $modified');
},
)
],
),
);
}
}
class TextList extends FormField<List<String>> {
TextList({List<String> initialValue, FormFieldSetter<List<String>> onSaved})
: super(
initialValue: initialValue,
onSaved: onSaved,
builder: (state) {
//Make a copy
List<String> _value = List.of(state.value);
//This just creates the list of MyFancyTextFormField
List<Widget> fields = _value
.asMap()
.map<int, Widget>((i, val) => MapEntry(
i,
MyFancyTextFormField(
initialValue: _value[i],
onSaved: (val) {
print('MyFancyTextFormField[$i] saved with $val');
state.didChange(_value..replaceRange(i, i + 1, [val]));
})))
.values
.toList();
return Column(
children: fields,
);
});
}
class MyFancyTextFormField extends FormField<String> {
MyFancyTextFormField({
String initialValue,
FormFieldSetter<String> onSaved,
}) : super(
initialValue: initialValue,
onSaved: (value) => onSaved(value),
builder: (state) => TextFormField(
initialValue: initialValue,
onSaved: onSaved,
));
}
问题是,当我保存()表单状态时,框架将首先保存我的顶级FormField TextList,而不是叶级FormField MyFancyTextFormField。
这是我的输出:
I/flutter ( 615): TextList saved with: [one, two, three]
I/flutter ( 615): MyFancyTextFormField[0] saved with one
I/flutter ( 615): MyFancyTextFormField[0] saved with oneee
I/flutter ( 615): MyFancyTextFormField[1] saved with two
I/flutter ( 615): MyFancyTextFormField[1] saved with two
I/flutter ( 615): MyFancyTextFormField[2] saved with three
I/flutter ( 615): MyFancyTextFormField[2] saved with threeeeeeeeee
I/flutter ( 615): Initial value was: [one, two, three], modified value is: [one, two, three]
自从第一次执行save()之后,我的TextList的状态就正确更新了,如果再次运行save(),我将得到预期的输出:
I/flutter ( 615): TextList saved with: [oneee, two, threeeeeeeeee]
I/flutter ( 615): MyFancyTextFormField[0] saved with one
I/flutter ( 615): MyFancyTextFormField[0] saved with oneee
I/flutter ( 615): MyFancyTextFormField[1] saved with two
I/flutter ( 615): MyFancyTextFormField[1] saved with two
I/flutter ( 615): MyFancyTextFormField[2] saved with three
I/flutter ( 615): MyFancyTextFormField[2] saved with threeeeeeeeee
I/flutter ( 615): Initial value was: [one, two, three], modified value is: [oneee, two, threeeeeeeeee]
为什么MyFancyTextFormField(s)的onSaved调用两次?
有没有一种方法可以使我获得预期的结果,而不是将state.save()召回为FormField树高多少倍?
谢谢。
答案 0 :(得分:1)
答案很晚,但是我认为这是因为MyFancyTextFormField
扩展了FormField
并在生成器中返回了另外的TextFormField
。如果将MyFancyTextFormField
变成返回TextFormField
的无状态小部件,您将得到想要的东西:
class MyFancyTextFormField extends StatelessWidget {
final String initialValue;
final FormFieldSetter<String> onSaved;
MyFancyTextFormField({
this.initialValue,
this.onSaved,
}) ;
@override
Widget build(BuildContext context) {
return TextFormField(
initialValue: initialValue,
onSaved: this.onSaved);
}
}