dart - ListView 未使用 StatefulWidget 重新加载
问题描述
我正在制作一个演示用于学习目的。在我刚刚添加的那个演示中ListView
,当我点击ListTile
那里时,Icons.favorite
我只想做 Active 和 Deactive。
下面是我的代码。
import 'package:flutter/material.dart';
void main() => runApp(new RandomWordApp());
class RandomWordApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
title: "Random App",
home: new RandomWordHome(),
);
}
}
class RandomWordHome extends StatefulWidget {
@override
createState() => new RandomState();
}
class RandomState extends State<RandomWordHome> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: new Text("Random Word"),
),
body: setupListView(),
);
}
Widget setupListView() {
final _arrayOfData = [
{
"name": "Amit Patel",
"address": "Junagadh"
},
{"name": "Arjun Jain", "address": "Madhya Pradesh"},
{"name": "Ajay Shah", "address": "Limbadi"},
{"name": "Ankur Patel", "address": "Visanagar"},
{"name": "Soheb Ansari", "address": "Ahmedabad"}
];
final _arraySelectedRowStatus = List.filled(5, 0);
return new ListView.builder(
padding: new EdgeInsets.all(10.0),
itemCount: _arrayOfData.length,
itemBuilder: (context, i) {
return new ListTile(
title: new Text(_arrayOfData[i]["name"]),
subtitle: new Text(_arrayOfData[i]["address"]),
leading: new CircleAvatar(
backgroundColor: Colors.blue,
child: new Text(_arrayOfData[i]["name"][0])),
trailing: new Icon(
(_arraySelectedRowStatus[i] == 0
? Icons.favorite_border
: Icons.favorite),
color: (_arraySelectedRowStatus[i] == 0 ? null : Colors.red),
),
onTap: () {
setState(
() {
_arraySelectedRowStatus[i] =
(_arraySelectedRowStatus[i] == 0 ? 1 : 0);
Scaffold.of(context).showSnackBar(new SnackBar(
content:
new Text("You are selecting at " + i.toString())));
},
);
},
);
});
}
}
一切都运行良好,即使我从下一行得到了预期的输出
print(_arrayOfData[i]["name"] + " - " + _arraySelectedRowStatus[i].toString());
但是Icon
没有改变可能是因为 ListView 没有重新加载。我哪里错了?引导我正确的方向。
解决方案
您的方法存在一些问题
为了更新你的 UI,你必须使用 setState() 方法。改变变量是不够的。
您总是在 ListView.builder 块内创建一个最终列表:final _arraySelectedRowStatus = List.filled(5, 0); 然后使用这个列表来呈现你的 UI。因此 _arraySelectedRowStatus 将始终包含0。
下面是更新的代码,它将起作用
import 'package:flutter/material.dart';
void main() => runApp(new RandomWordApp());
class RandomWordApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
title: "Random App",
home: new RandomWordHome(),
);
}
}
class RandomWordHome extends StatefulWidget {
@override
createState() => new RandomState();
}
class RandomState extends State<RandomWordHome> {
List _arraySelectedRowStatus = List.filled(5, 0);
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: new Text("Random Word"),
),
body: setupListView(),
);
}
Widget setupListView() {
final _arrayOfData = [
{"name": "Amit Patel", "address": "Junagadh"},
{"name": "Arjun Jain", "address": "Madhya Pradesh"},
{"name": "Ajay Shah", "address": "Limbadi"},
{"name": "Ankur Patel", "address": "Visanagar"},
{"name": "Soheb Ansari", "address": "Ahmedabad"}
];
return new ListView.builder(
padding: new EdgeInsets.all(10.0),
itemCount: _arrayOfData.length,
itemBuilder: (context, i) {
return new ListTile(
title: new Text(_arrayOfData[i]["name"]),
subtitle: new Text(_arrayOfData[i]["address"]),
leading: new CircleAvatar(
backgroundColor: Colors.blue,
child: new Text(_arrayOfData[i]["name"][0])),
trailing: new Icon(
(_arraySelectedRowStatus[i] == 0
? Icons.favorite_border
: Icons.favorite),
color: (_arraySelectedRowStatus[i] == 0 ? null : Colors.red),
),
onTap: () {
_arraySelectedRowStatus[i] =
(_arraySelectedRowStatus[i] == 0 ? 1 : 0);
print(_arrayOfData[i]["name"] +
" - " +
_arraySelectedRowStatus[i].toString());
setState(() {
_arraySelectedRowStatus = _arraySelectedRowStatus;
});
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text("You are selecting at " + i.toString())));
},
);
});
}
}