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

Android Navigation切换页面时Safe Args参数持续留存问题如何解决?

问题原因

使用Navigation组件搭配底部导航时,同一目的地的Fragment实例默认会被复用,仅会销毁重建视图(执行onDestroyView -> onCreateView生命周期),实例本身不会被销毁。
而Safe Args的参数是存储在Fragment的arguments Bundle对象中,只要Fragment实例存在,arguments内存储的数值就不会自动重置。你设置的默认null值仅在Fragment首次创建、arguments中无对应参数key时生效,一旦参数被赋值后,后续回到该Fragment都不会再读取默认值,因此会出现参数残留的问题。

解决方案

提供两种可直接落地的方案,可根据业务需求选择:

方案1:参数消费后手动清空(改动最小)

仅需在A Fragment消费完参数后,手动移除arguments内对应的参数key即可,下次回到Fragment时就会自动读取默认的null值。
修改后A Fragment的onViewCreated代码如下:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    args.workout?.let { workout ->
        vm.addRoutine(workout)
        // 新增这行,消费完直接删除参数,避免残留
        arguments?.remove("workout")
    }

    vm.items.observe(viewLifecycleOwner) { updatedItems ->
        adapter.setItems(updatedItems)
    }
}

方案2:使用官方推荐的Fragment返回结果API(无残留隐患,最佳实践)

不需要用Safe Args回传参数,改用Android官方提供的FragmentResultAPI,该API的回调是一次性的,仅在目标页面返回时触发一次,天然不存在参数残留问题:

  1. 先删除nav_graph中为A Fragment配置的workout参数配置,不需要再用Safe Args接收回传值
  2. 在A Fragment的onViewCreated中注册结果回调:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    // 注册返回结果监听,仅当B页面返回时触发
    setFragmentResultListener("workout_request_key", viewLifecycleOwner) { _, bundle ->
        val workout = bundle.getString("workout")
        workout?.let { vm.addRoutine(it) }
    }

    vm.items.observe(viewLifecycleOwner) { updatedItems ->
        adapter.setItems(updatedItems)
    }
}
  1. 在B Fragment需要返回A的位置,替换原有Safe Args传值逻辑:
// 先设置返回结果
setFragmentResult("workout_request_key", bundleOf("workout" to "你要回传的参数值"))
// 再执行返回操作
findNavController().popBackStack()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:27:02