如何在颤振中获取列表视图滚动的索引号?

How to get the index number on scroll for listview in flutter?

我在 flutter 应用程序中为列表视图构建器使用以下代码我需要在滚动时获取列表中项目的索引。就像使用 PageView.Builder

onPageChanged:(){} 的功能一样
return ListView.builder(
              itemCount: posts.length,
              itemBuilder: (context, index) {
                final item = posts[index];
                return Post(index: index, title: 'Test', imageUrl: 'https://www.google.com',);
              },
            );

我怎样才能得到它?

没有这么简单的方法,但您可以使用 visibility_detector 包中的 VisibilityDetector

通过用 VisibilityDetector.

包裹每个列表项,您可以获得在屏幕上完全可见的最后一个列表项的索引
itemBuilder: (context, index) {
  return VisibilityDetector(
    key: Key(index.toString()),
    onVisibilityChanged: (VisibilityInfo info) {
      if (info.visibleFraction == 1)
        setState(() {
          _currentItem = index;
          print(_currentItem);
        });
    },
    child: Post(index: index, title: 'Test', imageUrl: 'https://www.google.com',)
  );
},

_currentItem 是主小部件状态中的一个变量,用于存储最后一个可见项目的索引:

int _currentItem = 0;

注意:这是基于滚动方向的,即最后一个可见项目的索引等于滚动后最后一个可见项目的索引;如果向前滚动,它是屏幕底部项目的索引,但如果反向滚动,它是屏幕顶部项目的索引。不过这个逻辑可以很容易地改变(例如,使用队列来存储可见项目总数)。

我遇到了同样的问题,然后这样解决了:

起初我创建了一个 ScrollController,Size 来获取屏幕尺寸和一个变量来存储活动索引:

late final ScrollController _controller;
int _pageIndex = 1;
Size size = MediaQuery.of(context).size;

之后我将整个 ListView 包装到一个 NotificationListener 中,并且在 onNotification 部分我使用了这样的逻辑:

setState(() { _pageIndex = (_controller.offset/MediaQuery.of(context).size.height).round() + 1; });

因此,当您滚动列表视图时,_pageIndex 变量将始终包含活动索引。

为了更容易理解,增加了一部分代码:

NotificationListener(
          onNotification: (t) {
            setState(() { _pageIndex = (_controller.offset / MediaQuery.of(context).size.height).round() + 1;
            });
            return true;
          },
          child: ListView(
            itemExtent: size.height,
            controller: _controller,
            children: [
              SizedBox(
                width: size.width,
                height: size.height,
                child: Center(
                  child: Text("1"),
                ),
              ),
              SizedBox(
                width: size.width,
                height: size.height,
                child: Center(
                  child: Text("2"),
                ),
              ),
              SizedBox(
                width: size.width,
                height: size.height,
                child: Center(
                  child: Text("3"),
                ),
              ),
            ],
          ),
        ),

希望对您有所帮助!