Jetpack Navigation如何从嵌套图子页面跳转另一嵌套图非首页子页面
跨Jetpack嵌套导航图跳转非首页子目的地解决方案
现有导航结构如下:
MainActivity |- nav_root |- HomeFragment |- AuthNestedGraph | |- nav_auth | | |-BeforeOtpFragment(home) | | |-OtpFragment | |- ProfileNestedGraph | |- nav_prfole | | |-ProfileFragmentOne(home) | | |-ProfileFragmentTwo
报错核心原因
cannot be found from the current destination Destination报错的根源是:嵌套导航图的内部子目的地ID仅在当前子图作用域内可见,定义在子图内的全局动作无法被其他导航图的目的地识别,默认全局动作仅支持跳转到目标子图的首页目的地。
以下是3种无需深层链接的实现方案:
方案1:嵌套图首页中转传参
在全局跳转动作中携带目标子目的地ID,跳转至目标嵌套图首页后,由首页判断参数直接跳转到对应子页面,可选择是否把中转页弹出回退栈。
- 在根导航图
nav_root中定义带参数的全局跳转动作:
<!-- 跳转到Auth模块嵌套图的全局动作 --> <action android:id="@+id/action_global_to_auth_graph" app:destination="@id/authNestedGraph"> <argument android:name="targetDestinationId" android:defaultValue="0" app:argType="integer" /> </action>
- 触发跳转时传入目标子目的地ID:
val bundle = bundleOf("targetDestinationId" to R.id.otpFragment) findNavController().navigate(R.id.action_global_to_auth_graph, bundle)
- 在Auth模块首页
BeforeOtpFragment中处理跳转逻辑:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val targetId = arguments?.getInt("targetDestinationId", 0) ?: 0 if (targetId != 0) { findNavController().navigate(targetId) // 可选:将中转页BeforeOtp弹出回退栈,返回时直接回到跳转前页面 findNavController().popBackStack(R.id.beforeOtpFragment, true) } }
方案2:动态修改嵌套图起始目的地
跳转前临时修改目标嵌套图的起始目的地为你要跳转的子页面,跳转后可按需改回默认起始页。
val navController = findNavController() // 获取根导航图中对应的目标嵌套图实例 val authGraph = navController.graph.findNode(R.id.authNestedGraph) as NavGraph // 临时修改嵌套图的起始目的地为OtpFragment authGraph.setStartDestination(R.id.otpFragment) // 执行跳转 navController.navigate(authGraph.id) // 可选:将嵌套图的起始目的地改回默认的BeforeOtpFragment,不影响后续正常跳转 authGraph.setStartDestination(R.id.beforeOtpFragment)
方案3:根导航图定义全局子目的地动作
直接在最外层的nav_root导航图中定义指向子页面的全局动作,所有嵌套图的目的地都可以识别该动作。
- 在
nav_root.xml中添加全局动作:
<!-- 直接指向OtpFragment的全局动作,定义在根图层级 --> <action android:id="@+id/action_global_to_otpFragment" app:destination="@id/otpFragment" />
- 任意页面直接调用动作跳转即可:
findNavController().navigate(R.id.action_global_to_otpFragment)
注意事项
- 跳转前可调用
navController.currentDestination?.getAction(actionId)校验动作是否存在,避免异常崩溃 - 若需要自定义回退逻辑,可通过
popUpTo、popUpToInclusive参数调整回退栈规则
内容的提问来源于stack exchange,提问作者Boris Sadakov
相关产品推荐
相关产品推荐

