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

使用Bottom Navigation View切换标签页时如何保存RecyclerView状态

解决方案

问题根因

该状态丢失问题是Navigation Component默认切换标签页时会销毁旧Fragment实例、重建新实例导致的,进入详情页返回时没有销毁Fragment实例,所以滚动状态可以正常保留。

修复步骤

1. 升级Navigation依赖到2.4.0及以上版本

该版本开始原生支持Bottom Navigation多返回栈特性,每个标签页的Fragment状态会独立保存,无需自行实现Fragment复用逻辑。
修改模块级build.gradle依赖:

implementation "androidx.navigation:navigation-fragment-ktx:2.7.5"
implementation "androidx.navigation:navigation-ui-ktx:2.7.5"

2. 正确绑定BottomNavigationView和NavController

不要自定义OnItemSelectedListener处理页面跳转,直接使用官方扩展方法绑定,会自动开启多返回栈能力:

val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
binding.bottomNav.setupWithNavController(navController)

注意需保证bottom_nav_menu.xml中每个item的id,和nav_graph.xml中对应标签页Fragment的id完全一致。

3. 规范数据和状态存储逻辑

  • 所有电影列表数据存储在对应标签页Fragment的独立ViewModel中,不要在onViewCreated生命周期中每次切回页面都重新发起列表请求,避免列表重新渲染导致滚动位置重置。
  • 如确实需要切回页面刷新数据,提前保存滚动状态,待数据更新完成后再恢复:
// 页面切走时保存滚动状态
private var listScrollState: Parcelable? = null
override fun onPause() {
    super.onPause()
    listScrollState = binding.movieRv.layoutManager?.onSaveInstanceState()
}

// 列表数据更新完成后恢复滚动状态
movieAdapter.submitList(fetchedMovieList) {
    listScrollState?.let { state ->
        binding.movieRv.layoutManager?.onRestoreInstanceState(state)
    }
}

4. 避免主动清空状态的操作

不要在onDestroyView生命周期中执行RecyclerView的adapter置空、LayoutManager重置等操作,这类操作会主动清除已保存的滚动状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:27:03