使用Jetpack Navigation实现HomeNavHostFragment向HomeFragment传递数据的问题及解决方法
问题场景
你有一个作为嵌套导航宿主的HomeNavHostFragment,内部通过FragmentContainerView承载nav_graph_home导航图,想要把参数从HomeNavHostFragment传递到导航图的起始页面HomeFragment,但尝试用主导航控制器设置导航图并携带Bundle的方式没有效果:
var bundle = bundleOf("KEY" to "SAMPLE") mainNavController.setGraph(R.navigation.nav_graph_home,bundle)
问题根源
你操作的是主导航控制器,但实际需要传参的是嵌套导航宿主对应的子导航控制器;同时你的布局文件里已经通过app:navGraph="@navigation/nav_graph_home"提前绑定了导航图,导致导航图在你准备传参之前就已经初始化完成,参数自然无法传递进去。
正确解决步骤
1. 修改布局文件,移除预绑定的导航图
打开fragment_navhost_home.xml,删除FragmentContainerView中的app:navGraph="@navigation/nav_graph_home"属性,避免导航图提前初始化:
<androidx.fragment.app.FragmentContainerView android:id="@+id/nested_nav_host_fragment_home" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:defaultNavHost="false" />
2. 在HomeNavHostFragment中使用子导航控制器传参
在HomeNavHostFragment的onViewCreated方法中,获取嵌套导航的控制器,再通过它设置导航图并携带参数:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val mainNavController = Navigation.findNavController(requireActivity(), R.id.nav_host_fragment) val nestedNavHostFragment = childFragmentManager.findFragmentById(nestedNavHostFragmentId) as? NavHostFragment navController = nestedNavHostFragment?.navController // 新增:通过子导航控制器传递参数 val bundle = bundleOf("KEY" to "SAMPLE") navController?.setGraph(R.navigation.nav_graph_home, bundle) listenOnBackPressed() }
3. 在HomeFragment中接收参数
最后在HomeFragment里就能正常获取传递过来的参数了:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val sampleParam = arguments?.getString("KEY") // 这里可以用参数做后续业务逻辑处理 }
核心总结
处理嵌套导航的参数传递时,一定要操作对应的子导航控制器,同时要避免在布局中提前绑定导航图,确保参数能在导航图初始化的时机被正确传递到起始Fragment。
内容的提问来源于stack exchange,提问作者Thang
相关产品推荐
相关产品推荐

