当表单滚动到屏幕外时,如何保存每个表单字段的状态?当我向上滚动时,我丢失了我在 TextFormFields 中键入的值字段在屏幕外。
我听说过将它保存在控制器中然后分配给TextFormField的initialvalue的建议,如代码所示,但它对我不起作用。我错过了什么?
TextEditingController _controller = new TextEditingController();
@override
Widget build(BuildContext context) {
return new Scaffold(
key: scaffoldKey,
appBar: new AppBar(
title: new Text('Enter Vehicle'),
),
body: new Padding(
padding: const EdgeInsets.all(16.0),
child: new Form(
key: formKey,
child: new ListView(children: <Widget>[
new TextFormField(
decoration: new InputDecoration(labelText: 'Vehicle Number'),
controller: _controller,
initialValue: _controller.text,
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Tag'),
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Make'),
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Model'),
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Year'),
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Vehicle Type'),
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Location'),
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Fuel'),
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Other'),
),
new TextFormField(
decoration: new InputDecoration(labelText: 'Your password'),
validator: (val) =>
val.length < 6 ? 'Password too short.' : null,
onSaved: (val) => _password = val,
obscureText: true,
),
new RaisedButton(
onPressed: _submit,
child: new Text('Login'),
),
],)
)
),
);
}
答案 0 :(得分:1)
new Container(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 0.0, bottom: 0.0),
child: new EnsureVisibleWhenFocused(
focusNode: _focusNode_nooftickets,
child: new TextFormField(
controller: _ticketscontroller,
initialValue: _ticketscontroller.text,
focusNode: _focusNode_nooftickets,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
WhitelistingTextInputFormatter.digitsOnly
],
validator: validatenooftickets,
onSaved: (String value) {
ticketmode.nooftickets = value;
},
),
),
),
答案 1 :(得分:1)
在使用TextFormField时,您不需要那样使用initialValue。实际上,如果_controller.text
为null,则会给出断言错误。
要使TextFormFields正常工作,请确保:
工作示例:
class MyForm extends StatefulWidget {
@override
_MyFormState createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
TextEditingController _vehicleNumber;
@override
void initState() {
super.initState();
_vehicleNumber = new TextEditingController();
}
@override
void dispose() {
super.dispose();
_vehicleNumber.dispose();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Enter Vehicle'),
),
body: new Padding(
padding: const EdgeInsets.all(16.0),
child: new Form(
child: new ListView(
children: <Widget>[
new TextFormField(
decoration: new InputDecoration(labelText: 'Vehicle Number'),
controller: _vehicleNumber,
),
// All the other fields here
// All should have its own controller
],
))),
);
}
}
答案 2 :(得分:0)
每个TextEditingController
都需要专门的TextFormField
,我认为您不需要在这些字段上使用initialValue
属性。
看一下这个答案https://stackoverflow.com/a/45242235/6414732,这也许有帮助。
答案 3 :(得分:0)
有两种解决方案:
因此,尽管TextFormField派生自其中的FormField是有状态的,但将其放入任何描述的列表中将有重建它的风险。
选项1:
将List
更改为Column
并将其包装在List
或SingleChildListView
中,它既快捷又容易破解,但可能会影响很多商品的性能 >
List(
children: [...]
)
nb。如果您有listview.builder,则需要将其映射出来而不使用该生成器,否则请转到选项2。
到
SingleChildScrollView(
child: Column(
children: [...]
)
)
选项2:
为每个字段创建一个控制器并将其保存在父窗口小部件中,或将数据保存到地图并设置其初始数据。您可以解决它,但是无论哪种方式都需要将其保存在父窗口小部件中。