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

如何在navController控制的底部导航菜单场景下保存Fragment的状态

解决方案

针对底部导航切换Fragment、屏幕旋转两种场景下的数据丢失问题,可以根据你的业务需求选择以下几种方案:

1. 使用ViewModel存储业务数据(官方首推,适配两种场景)

该方案可以同时覆盖配置变更(旋转屏幕)、导航切换导致的Fragment销毁重建场景:

  • 自定义ViewModel类,将所有需要保留的输入框内容、列表数据、选中状态等业务数据定义为ViewModel的成员变量
  • 实例化ViewModel时绑定宿主Activity的生命周期,示例代码:
    // Kotlin 示例
    val myViewModel = ViewModelProvider(requireActivity())[MyViewModel::class.java]
    
    // Java 示例
    MyViewModel myViewModel = new ViewModelProvider(requireActivity()).get(MyViewModel.class);
    
  • 在Fragment的onViewCreated生命周期中,直接从ViewModel读取数据回填到对应的布局组件中;用户修改数据时同步更新ViewModel中的对应值
  • 注意不要在ViewModel中持有View、Activity等上下文类的引用,避免内存泄漏

2. 配合onSaveInstanceState保存轻量界面状态

该方案适合保存控件滚动位置、输入框焦点、临时选中状态等轻量界面数据,主要适配配置变更场景,如需适配导航切换需要配合Navigation组件的多回退栈配置:

  • 重写Fragment的onSaveInstanceState方法,将需要保存的数据存入Bundle参数:
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString("input_content", binding.editText.text.toString())
        outState.putInt("select_position", selectPosition)
    }
    
  • 在onViewCreated中判断savedInstanceState是否非空,非空时直接读取数据回填:
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        savedInstanceState?.let {
            binding.editText.setText(it.getString("input_content"))
            selectPosition = it.getInt("select_position")
        }
    }
    
  • 如果是Navigation组件版本低于2.4.0,需要开启多回退栈支持才能在底部导航切换时保存状态:给底部导航菜单的每个item添加android:menuCategory="secondary"属性,或者在导航跳转配置中添加popUpToSaveState="true"和restoreState="true"属性。2.4.0及以上版本默认开启多回退栈支持,无需额外配置。

3. 本地持久化存储(适配进程销毁场景)

如果需要在App退后台被杀死、重启后依然保留数据,可以选择SharedPreferences、Room数据库等本地存储方案:

  • 每次用户修改数据时同步写入本地存储
  • Fragment初始化时从本地读取数据回填到组件中

内容的提问来源于stack exchange,提问作者G.C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:15:05