listview - 为什么每次在 0 索引处插入新项目时都会触发所有列表项目的 "initState()"方法?

标签 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

这种情况有什么解决方法吗?我希望以前添加的列表项保持旧状态。

我尝试将列表视口(viewport)的轴方向更改为向上(将ListViewreverse 属性更改为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/

相关文章:

Flutter dart_ping 包不工作。那么如何ping 172.18.43.140之类的远程ip呢?

flutter 检测装置类型

javascript - onChange仅在2次文本输入后触发

android - OnItemClick 和项目 View

android - 子元素的阴影在 flutter 中改变了一个 wrap 中的位置

android - setAdapter() 上的空指针异常

dart - 如何在 Dart 中获取一个类的所有字段?

dart - 如何取消 Future.delayed?

firebase-realtime-database - 如何在 Dart 中使用 await 而不是 .then()

flutter - 使用 Scoped 模型显示对话框