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

从Firestore拉取更新数据后如何保持RecyclerView的原有滚动位置不变

修复RecyclerView更新数据后滚动到顶部的方案

问题根源

你当前每次拉取到Firestore返回的商品列表后,都会重新给RecyclerView设置LayoutManager、重新创建Adapter实例并绑定到RecyclerView,这是触发列表自动滚动到顶部的核心原因。你额外添加的notifyDataSetChanged在这里没有任何作用,因为替换整个Adapter本身就会重置列表的所有状态包括滚动位置。

修复步骤

1. 全局初始化Adapter和LayoutManager

将Adapter、LayoutManager的初始化逻辑移到页面创建阶段(比如Fragment的onViewCreated中),全程只初始化一次:

// 全局保存列表数据和Adapter实例
private lateinit var adapterProducts: MyProductsListAdapter
private val productList = arrayListOf<Product>()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    // 初始化逻辑只执行一次
    binding.rvMyProductItems.layoutManager = LinearLayoutManager(activity)
    binding.rvMyProductItems.setHasFixedSize(true)
    adapterProducts = MyProductsListAdapter(requireActivity(), productList, this@ProductsFragment)
    binding.rvMyProductItems.adapter = adapterProducts
}

2. 改造拉取成功的回调逻辑

不要每次都创建新的Adapter,只更新原有Adapter绑定的数据集即可:

fun successProductsListFromFireStore(productsList: ArrayList<Product>) {
    hideProgressDialog()

    if (productsList.size > 0) {
        binding.rvMyProductItems.visibility = View.VISIBLE
        binding.tvNoProductsFound.visibility = View.GONE
        // 更新原有列表的内容
        this.productList.clear()
        this.productList.addAll(productsList)
        // 通知Adapter刷新,此时不会重置滚动位置
        adapterProducts.notifyDataSetChanged()
    } else {
        binding.rvMyProductItems.visibility = View.GONE
        binding.tvNoProductsFound.visibility = View.VISIBLE
    }
}

3. 可选优化(推荐)

用DiffUtil替换全局的notifyDataSetChanged,实现局部刷新:

  • 实现DiffUtil.ItemCallback<Product>对比新旧商品条目差异
  • 计算差异后调用diffResult.dispatchUpdatesTo(adapterProducts)
    可以完全避免不必要的条目刷新、消除列表跳动,滚动位置保留的体验更好。

进阶方案

如果你的增删改操作都是单条数据变更,不需要每次拉取全量商品列表,可以直接监听Firestore对应单条数据的变化,收到变更通知后对应调用adapter.notifyItemInserted/notifyItemRemoved/notifyItemChanged,完全不会影响列表的滚动位置,性能也更高。

内容的提问来源于stack exchange,提问作者Codist

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:06:04