我想将新的小部件(StatefulWidget)添加到ListView到列表items.insert(0, listItem)
的顶部,但是当我这样做时,列表的所有元素都再次初始化(initState()
hook是每次都打电话)
如果我将项目添加到列表items.add(listItem)
的底部-一切都会按预期进行({initState()
仅在新添加的元素上被调用。)
用于演示的代码
class ListItem extends StatefulWidget {
final String label;
const ListItem({Key key, @required this.label}) : super(key: key);
_ListItemState createState() => _ListItemState();
}
class _ListItemState extends State<ListItem> {
@override
void initState() {
super.initState();
print('initState() ${this.widget.label}');
}
@override
Widget build(BuildContext context) {
return Text(this.widget.label);
}
}
在addItem()
函数内部添加新元素:
class ItemsList extends StatefulWidget {
State<StatefulWidget> createState() => ItemsListState();
}
class ItemsListState extends State<ItemsList> {
var items = List<ListItem>();
@override
Widget build(BuildContext context) {
return GestureDetector(
child: ListView(children: items),
onTap: addItem);
}
void addItem() {
final label = items.length.toString();
print('Add $label');
final listItem = ListItem(key: ValueKey(label), label: label);
items.insert(0, listItem);
this.setState(() {
items = []..addAll(items);
});
}
}
调用addItem()
函数3次(例如)时控制台输出:
Add 0
initState() 0
Add 1
initState() 1
initState() 0
Add 2
initState() 2
initState() 1
initState() 0
当新项目追加到列表的底部(items.add(listItem)
而不是items.insert(0, listItem)
)时的预期输出
Add 0
initState() 0
Add 1
initState() 1
Add 2
initState() 2
对于这种情况是否有任何解决方法?我希望以前添加的列表项保持旧状态。
我试图将列表视口的轴方向更改为up
(将reverse
的{{1}}属性更改为ListView
),但是得到了相同的结果。
答案 0 :(得分:0)
那是因为您正在更改商品的订购键。
ListView(
children: items,
reverse: true,
)
和
final listItem = ListItem(key: ValueKey(label), label: label);
items.add(listItem);
this.setState(() {
items = List.from(items);
});
应该工作