学习:snapshotFlow { listState.layoutInfo }

2 阅读3分钟

我用最简单、最直白、最通俗 的方式给你讲懂 snapshotFlow { listState.layoutInfo } 到底是什么?

一句话核心解释

kotlin

snapshotFlow { listState.layoutInfo }

意思是:

监听列表布局信息的变化,把它变成一个可观察的流。只要列表滑动、布局改变,这里就会自动发出新值。
val listState = rememberLazyListState()

//全部代码
LaunchedEffect(listState) {
    snapshotFlow { listState.layoutInfo }
        .distinctUntilChanged() // 关键:防止重复触发
        .collect { layoutInfo ->
         }
}

一、先拆成 2 部分看

① listState.layoutInfo

它是列表当前的状态

  • 总共有多少条数据
  • 屏幕上可见哪几条
  • 第一条、最后一条索引是多少

它会在:滑动、数据变化、布局变化 时自动改变。

② snapshotFlow { ... }

把 Compose 的状态变化 → 转换成 Kotlin 流(Flow)

作用:

你可以持续监听某个状态的变化

就像:

“只要这个值变了,就通知我,我要处理。”

二、为什么列表加载更多必须用它?

因为:

**LaunchedEffect 只能监听一次 key 变化,

而 snapshotFlow 可以持续监听滑动。**

如果你写:

kotlin

LaunchedEffect(listState.layoutInfo) {
   // 只会执行一次!
   // 滑动不会触发!
}

滑动列表不会触发加载更多!

但用:

kotlin

snapshotFlow { listState.layoutInfo }
    .collect {
        // 滑动一次,执行一次
    }

滑动就会持续触发!

三、结合我们的代码:它到底做了什么?

kotlin

snapshotFlow { listState.layoutInfo }
    .distinctUntilChanged()
    .collect { layoutInfo ->
        // 每次滑动列表,都会来这里!
        // 拿到当前列表的:总条数、最后可见位置
    }

作用:

监听用户滑动列表 → 判断是否滑到底部 → 触发加载更多

1、distinctUntilChanged() 到底是啥?

一句话:

只有数据【真正变化】了,才往下走;一模一样的数据,直接忽略,不执行。

2、用生活例子讲

你在盯着一个数字看:

  • 数字变成 1 → 你看到了,处理
  • 数字还是 1 → 你不理它
  • 数字变成 2 → 你才处理
  • 数字又变成 2 → 你还是不理

这就是 distinctUntilChanged()

3、放在 Compose 列表里是什么效果?

列表滑动时,listState.layoutInfo 会疯狂、连续、重复地输出相同的值

如果不加 distinctUntilChanged()

  • 滑一下 → 触发 10 次加载更多
  • 第一次进页面 → 自动触发
  • 下拉刷新 → 乱触发
  • 你的接口会被疯狂调用

加了之后:

  • 相同的状态 → 直接过滤,不执行
  • 只有状态真的变了 → 才执行
  • 第一次进页面不会触发
  • 滑动到底才触发一次
4、代码里的作用

kotlin

snapshotFlow { listState.layoutInfo }
    .distinctUntilChanged() // 👈 就是这里
    .collect { ... }

意思:

过滤掉重复、连续、一样的滑动状态

只保留真正有用、真正变化的事件。

5、超级总结
distinctUntilChanged() = 去重、防重复、防乱触发
它是 Compose 列表上拉加载更多 必须加 的一行代码

四、 超级通俗比喻

  • listState.layoutInfo = 汽车时速表
  • snapshotFlow = 盯着时速表的摄像头
  • 车一动 → 时速表变 → 摄像头立刻告诉你

对应:

  • 手指滑动列表 → layoutInfo 变 → snapshotFlow 捕捉到 → 触发判断是否加载更多

五、 总结(你只需要记住这句)

snapshotFlow { listState.layoutInfo }

监听列表滑动,持续获取列表状态

它是 Compose 里实现上拉加载更多的官方标准方式