如何在ListView.builder flutter中正确使用findChildIndexCallback?

Tom*_*652 3 dart flutter

我正在尝试使用 来保持我内部findChildIndexCallback的状态。StatefulWidgetsListView.builder

有人可以提供一个例子来说明我如何真正“找到”Listview孩子们吗?

我的问题直接来自我提出的一个问题,该问题实际上已由 Flutter 团队修复。

这是我到目前为止不起作用的代码:

ListView.builder(
            itemCount: model.messagesList.length,
            findChildIndexCallback: (key) {
              // final ValueKey<String> valueKey = key as ValueKey<String>;
              // return model.messagesList.indexWhere((element) => element.uid == valueKey.value); // Doesn't change anything, my widgets are all rebuilt on insert
            },
            itemBuilder: (context, index) {
              DMessage message = model.messagesList[index];
              return MessageItem(
                key: ValueKey<String>(message.uid)
                message: message
              );
            }),
Run Code Online (Sandbox Code Playgroud)

Ala*_*ana 5

只需在您的项目小部件中StatefulWidget使用即可。AutomaticKeepAliveClientMixin子类必须实现wantKeepAlive,并且必须调用它们的构建方法super.build(BuildContext)

class ItemWidget extends StatefulWidget {
  const ItemWidget({Key? key, required this.item}) : super(key: key);

  final int item;

  @override
  State<ItemWidget> createState() => _ItemWidgetState();
}

class _ItemWidgetState extends State<ItemWidget>
    with AutomaticKeepAliveClientMixin {
  bool selected = false;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return ListTile(
      selected: selected,
      title: Text('Index-${widget.item}'),
      onTap: () {
        setState(() {
          selected = !selected;
        });
      },
    );
  }

  @override
  bool get wantKeepAlive => true;
}
Run Code Online (Sandbox Code Playgroud)

并提供findChildIndexCallback您的财产,ListView如下所示:

class ListWidget extends StatelessWidget {
  const ListWidget({Key? key, required this.items}) : super(key: key);

  final List<int> items;

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (context, index) {
        final item = items[index];
        return ItemWidget(key: ValueKey(item), item: item);
      },
      itemCount: items.length,
      findChildIndexCallback: (Key key) {
        final valueKey = key as ValueKey;
        final index = items.indexWhere((item) => item == valueKey.value);
        if (index == -1) return null;
        return index;
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这里是 dartpad https://dartpad.dev/?id=b02294906a0b0c77984126e62f5a048d

  • 点击列表中的任何项目,它将被选中
  • 使用 FAB 添加新项目,它会将新元素插入列表视图的随机索引中
  • 添加新项目后,已选择(状态)的项目将保持选择状态