我正在尝试使用状态存储的列表构建 TextField 的列表。我尝试使用 onChanged 方法从状态中更新特定值,但是这样做的方式无效。
以下是代码示例:
class AlarmLimitScreen extends StatefulWidget { AlarmLimitScreen();
@override _AlarmLimitScreenState createState() =>
_AlarmLimitScreenState(); }
class _AlarmLimitScreenState extends State<AlarmLimitScreen> { var alarmLimitLists = [];
void initState() {
super.initState();
_getAlarmLimitFromDb(); }
void _getAlarmLimitFromDb() async {
final alarmLimits = await DBProvider.db.getAlarmLimits();
// The data structure is similar to the default one below.
if (alarmLimits.length != 0) {
setState(() {
alarmLimitLists = alarmLimits;
});
} else {
//This is the default structure.
setState(() {
alarmLimitLists = [
{
"id": 1,
"name": "Field 1",
"key": "field1",
"min": null,
"max": null,
},
{
"id": 2,
"name": "Field 2",
"key": "field2",
"min": null,
"max": null,
},
{
"id": 3,
"name": "Field 3",
"key": "field3",
"min": null,
"max": null,
},
});
} }
void _submitAlarmLimit() async {
// Always print the default state
print("Saved=========: $alarmLimitLists"); }
@override Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Alarm Limits'),
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
_displayAlarmLimitLists(),
Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: ButtonTheme(
minWidth: 170.0,
height: 50.0,
child: RaisedButton(
onPressed: _submitAlarmLimit,
child: Text(
'Save',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w400,
),
),
color: Color(0xFFB7282C),
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
),
),
),
],
),
),
); }
Widget _displayAlarmLimitLists() {
return ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: alarmLimitLists.length,
itemBuilder: (context, int) {
return Container(
padding: EdgeInsets.symmetric(vertical: 6.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text(
alarmLimitLists[int]['name'],
style: TextStyle(
fontSize: 18.0,
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 4.0),
child: SizedBox(
width: 80,
height: 45,
child: TextField(
onChanged: (min) {
//===================================
//I'm changing the value here.
//===================================
alarmLimitLists[int]['min'] = min.toString();
setState(() {
alarmLimitLists = alarmLimitLists;
});
},
keyboardType: TextInputType.number,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Min',
),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: SizedBox(
width: 80,
height: 45,
child: TextField(
onChanged: (max) {
setState(() {
alarmLimitLists[int]['max'] = max;
});
},
keyboardType: TextInputType.number,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Max',
),
),
),
),
],
),
],
),
);
},
); } }
状态没有更新。
但是,如果我将 alarmLimitLists 存储为变量并在 onChanged 上对其进行修改,则它可以正常工作。