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

Android Kotlin:返回后再进入Activity B时保留RecyclerView状态

解决Android中RecyclerView在Activity重新启动时保留滚动位置的问题

方案一:让Activity B不被销毁(推荐)

通过拦截返回键让Activity退至后台而非销毁,再次启动时直接调至前台,RecyclerView的滚动状态会自然保留。

1. 修改Activity B的返回键行为

使用AndroidX的OnBackPressedCallback拦截返回键,调用moveTaskToBack(true)将任务移至后台:

class ActivityB : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_b)

        onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                moveTaskToBack(true)
            }
        })
    }
}

2. 调整Activity A启动B的逻辑

添加FLAG_ACTIVITY_REORDER_TO_FRONT标记,确保B已存在时直接调至前台,避免重建:

// Activity A中启动B的代码
btnStartB.setOnClickListener {
    val intent = Intent(this, ActivityB::class.java)
    intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
    startActivity(intent)
}

方案二:允许Activity B销毁,手动保存/恢复滚动位置

如果业务要求Activity B在返回时销毁,可在生命周期中保存滚动位置到持久化存储,下次启动时恢复。

实现代码(SharedPreferences版)

class ActivityB : AppCompatActivity() {
    private val sharedPref by lazy { getSharedPreferences("ActivityBState", MODE_PRIVATE) }
    private lateinit var recyclerView: RecyclerView
    private lateinit var layoutManager: LinearLayoutManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_b)
        
        recyclerView = findViewById(R.id.recyclerView)
        layoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager = layoutManager
        recyclerView.adapter = YourRecyclerViewAdapter(yourDataSource)
    }

    override fun onPause() {
        super.onPause()
        // 保存滚动位置与偏移量
        val firstVisiblePos = layoutManager.findFirstVisibleItemPosition()
        val offset = layoutManager.findViewByPosition(firstVisiblePos)?.top ?: 0
        
        sharedPref.edit()
            .putInt("scroll_pos", firstVisiblePos)
            .putInt("scroll_offset", offset)
            .apply()
    }

    override fun onResume() {
        super.onResume()
        // 恢复滚动位置
        val savedPos = sharedPref.getInt("scroll_pos", 0)
        val savedOffset = sharedPref.getInt("scroll_offset", 0)
        layoutManager.scrollToPositionWithOffset(savedPos, savedOffset)
    }
}

注意事项

  • 若RecyclerView数据源在重启后有更新,需确保恢复位置前数据源已加载完成,避免位置错乱。
  • 若使用ViewModel,其状态会随Activity销毁而丢失,因此不如SharedPreferences适合此场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:02:42