我想将新的小部件 (StatefulWidget) 添加到 ListView 到列表的顶部 items.insert(0, listItem)
,但是当我这样做时,列表的所有元素都是再次初始化(initState()
钩子(Hook)每次都在调用)
如果我将项目添加到列表底部 items.add(listItem)
- 一切都按预期工作(initState()
仅在新添加元素。)
演示代码
ListItem 小部件代码
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
这种情况有什么解决方法吗?我希望以前添加的列表项保持旧状态。
我尝试将列表视口(viewport)的轴方向更改为向上
(将ListView
的reverse
属性更改为true
) 但得到了相同的结果。
最佳答案
那是因为您正在更改商品的订购代码。
ListView(
children: items,
reverse: true,
)
和
final listItem = ListItem(key: ValueKey(label), label: label);
items.add(listItem);
this.setState(() {
items = List.from(items);
});
应该可以
关于listview - 为什么每次在 0 索引处插入新项目时都会触发所有列表项目的 "initState()"方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54246244/