You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Paging 3调用adapter.refresh()时如何避免列表自动滚动到顶部?

Paging 3 刷新不滚动到顶部解决方案

核心问题原因

你当前PagingSource中的getRefreshKey方法直接返回null,是触发刷新后列表回滚顶部的直接原因。Paging 3执行刷新操作时,会通过该方法获取当前列表可视区域对应位置的分页游标,以此为起点加载刷新后的数据,即可保持原有浏览位置。当返回值为null时,Paging会默认从初始页(第一页)开始加载,列表自然会滚动到顶部。

修复步骤

1. 重写getRefreshKey逻辑

修改你的SearchProductDataSource中的getRefreshKey方法,返回当前浏览位置对应的分页key:

override fun getRefreshKey(state: PagingState<String, Product>): String? {
    // 获取当前列表可视区域的锚点位置,无锚点直接返回null
    val anchorPosition = state.anchorPosition ?: return null
    // 获取锚点位置对应的分页信息
    val targetPage = state.closestPageToPosition(anchorPosition) ?: return null
    // 优先取当前页的下一页游标,无则取上一页游标
    return targetPage.nextKey ?: targetPage.prevKey
}

修改完成后调用adapter.refresh()就会从你当前浏览的分页位置开始加载,不会跳转到顶部。

2. 局部刷新优化(可选,适配心愿单更新场景)

如果你只是修改单条商品的心愿单状态,不需要调用全量刷新方法adapter.refresh(),直接局部更新对应条目即可,性能更好且完全不会触发列表滚动:

// 假设你已知要更新的商品在列表中的索引位置position
adapter.snapshot()[position]?.let { oldProduct ->
    // 生成修改心愿单状态后的新商品对象
    val updatedProduct = oldProduct.copy(isWished = !oldProduct.isWished)
    // 通知适配器局部更新该条目
    adapter.notifyItemChanged(position, updatedProduct)
}

注意事项

  • 确认你没有在适配器的addLoadStateListener监听刷新状态的逻辑中,主动调用了RecyclerView.scrollToPosition(0)这类滚动到顶部的代码,否则上述修改会被手动滚动逻辑覆盖。

内容的提问来源于stack exchange,提问作者a-rohim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:24:03