为什么在将新项目插入0索引时每次触发所有列表项目的“ initState()”方法?

时间:2019-01-18 00:32:39

标签: listview dart flutter

我想将新的小部件(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

对于这种情况是否有任何解决方法?我希望以前添加的列表项保持旧状态。

我试图将列表视口的轴方向更改为up(将reverse的{​​{1}}属性更改为ListView),但是得到了相同的结果。

1 个答案:

答案 0 :(得分:0)

那是因为您正在更改商品的订购键。

      ListView(
            children: items,
            reverse: true,
          )

     final listItem = ListItem(key: ValueKey(label), label: label);
        items.add(listItem);

        this.setState(() {
          items = List.from(items);
        });

应该工作