我的TextFormFields不能正常工作,当我单击它们并且键盘没有完全显示时,导致页面重建。
我有一个包含2个下拉菜单和多个文本字段的表单。下拉菜单确定显示哪些文本字段。我通过执行以下操作来确定这一点:
Form(
key: _formKey,
child: Flex(
direction: Axis.vertical,
children: <Widget>[
//category field
new FormField<String>(
validator: this.validateField,
builder: (FormFieldState<String> state) {
return new DropdownButtonHideUnderline(
child: DropdownButton<String>(
hint: new Text('Select Category'),
value: exercise.categoryName,
items: categoryNameList.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (String val) {
setState(() {
//save category name to the exercise object to be saved
exercise.categoryName = val;
state.didChange(val);
// reset exercise dropdown when switching categories
exercise = new Exercise(
categoryName: val, cardioImperial: -1);
// get index of the selected category to be able to load the correct
// exercise list
_exerciseSelectedTextIndex =
categoryNameList.indexOf(val);
_exerciseSelectedList =
categoryList[_exerciseSelectedTextIndex]
.exerciseNames;
});
},
));
}),
// only load the exercise list once the category is selected
_exerciseSelectedList != null
? Container(
child:
Flex(direction: Axis.vertical, children: <
Widget>[
new FormField(
validator: this.validateField,
builder: (FormFieldState<String> state) {
return new DropdownButtonHideUnderline(
child: DropdownButton<String>(
hint: new Text('Select Exercise'),
value: exercise.name,
items: _exerciseSelectedList
.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (String val) {
setState(() {
exercise.name = val;
state.didChange(val);
});
},
));
}),
]))
: Container(),
//if cardio load time/length else load reps/quantity
_exerciseSelectedList != null
? categoryList[_exerciseSelectedTextIndex].cardio ==
true
? Flex(direction: Axis.vertical, children: <
Widget>[
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
SizedBox(
width: 75.0,
child: TextFormField(
validator: this.validateField,
onSaved: (value) => exercise
.cardioLength = value,
keyboardType:
TextInputType.number,
decoration: InputDecoration(
hintText: 'Length',
),
)),
new Radio(
groupValue: exercise.cardioImperial,
value: 1,
onChanged: (value) => setState(() {
exercise.cardioImperial =
value;
}),
),
new Text('Miles'),
new Radio(
groupValue: exercise.cardioImperial,
value: 2,
onChanged: (value) => setState(() {
exercise.cardioImperial =
value;
}),
),
new Text('KM')
]),
// time fields
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: 30.0,
child: TextFormField(
validator: this.validateField,
onSaved: (value) =>
exercise.hh = value,
keyboardType:
TextInputType.number,
decoration: InputDecoration(
hintText: 'HH',
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: 30.0,
child: TextFormField(
validator: this.validateField,
onSaved: (value) =>
exercise.mm = value,
keyboardType:
TextInputType.number,
decoration: InputDecoration(
hintText: 'MM',
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: 30.0,
child: TextFormField(
validator: this.validateField,
onSaved: (value) =>
exercise.ss = value,
keyboardType:
TextInputType.number,
decoration: InputDecoration(
hintText: 'SS',
),
),
),
)
])
])
// if not cardio, load quantity/reps
: Flex(
direction: Axis.vertical,
children: <Widget>[
SizedBox(
width: 75.0,
child: TextFormField(
onSaved: (value) =>
exercise.quantity = value,
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: 'Weight',
),
),
),
// reps field
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: 50.0,
child: TextFormField(
onSaved: (value) =>
exercise.reps = value,
keyboardType:
TextInputType.number,
decoration: InputDecoration(
hintText: 'Reps',
),
),
),
),
])
: Container(),
],
))
我希望当我选择Cardio(cardio == true)时,可以单击可用的TextFormFields并可以输入数据。显示正确的字段,但是当我单击任何文本表单字段时,整个页面都会重建。有没有更好的方法来构造此页面以实现预期的行为?
答案 0 :(得分:1)
问题源于包含我的表单的Stateful小部件中的ScaffoldState和FormState。
我的应用程序的流程如下:
主页->第1页->第2页(带有表单)
最初,ScaffoldState和FormState驻留在Page2上。我保持相同的流程,但将ScaffoldState和FormState移至Page1,然后将它们传递给Page2,以供Form使用。现在,当我单击它时,TextFormField不会引起重建,并且保存功能可以按预期工作。