Compose Navigation报错:导航目标非NavGraph直接子节点如何解决
问题根因
这个报错本质是Jetpack Navigation在导航图中找不到你指定的启动目标路径,两次错误的具体原因分别如下:
第一次报错原因
你在嵌套导航图navigation方法中设置的startDestination是调用了带locationId参数的createRoute方法,生成的是替换了占位符的实际路径(比如manage_orders/manage_orders/123),但你注册ManageOrders页面用的是带占位符的模板路径manage_orders/manage_orders/{locationId},两者字符串不匹配,Navigation无法找到对应子节点,因此抛出异常。
第二次修改后仍然报错的原因
你错误将NavHost的startDestination改成了LeafScreen.ManageOrders.route,这个路径是嵌套导航图内部的子页面路径,不属于NavHost的顶层节点(你NavHost的builder中只添加了Screen.ManageOrders.route这一个顶层嵌套导航节点),Navigation在顶层找不到这个路径,因此仍然抛出相同异常。
正确修改方案
只需要调整3处即可修复问题:
- 把
NavHost的startDestination改回顶层存在的嵌套导航图路由Screen.ManageOrders.route - 嵌套导航图的
startDestination使用带占位符的模板路径,不要传入实际locationId替换 - 给
ManageOrders页面的LOCATION_ID参数设置默认值为传入的locationId,保证启动时能正确拿到参数
完整修正后的核心代码如下:
@ExperimentalCoroutinesApi @Composable internal fun AppNavigation( navController: NavHostController, locationId: String, modifier: Modifier = Modifier ) { NavHost( navController = navController, // 改回顶层存在的嵌套导航路由 startDestination = Screen.ManageOrders.route, modifier = modifier, ) { addManageOrdersTopLevel(navController, locationId) } } @ExperimentalCoroutinesApi private fun NavGraphBuilder.addManageOrdersTopLevel( navController: NavHostController, locationId: String ) { navigation( route = Screen.ManageOrders.route, // 用带占位符的模板路径作为启动目标,不要替换参数 startDestination = LeafScreen.ManageOrders.createRoute(Screen.ManageOrders) ) { addManageOrders( navController = navController, root = Screen.ManageOrders, locationId = locationId ) // 记得把详情页的注册加回来,否则跳转会报错 addManageOrderDetails(navController = navController, root = Screen.ManageOrders) } } private fun NavGraphBuilder.addManageOrders( navController: NavHostController, root: Screen, locationId: String ) { composable( route = LeafScreen.ManageOrders.createRoute(root), arguments = listOf( navArgument(LOCATION_ID) { type = NavType.StringType // 这里设置默认值为传入的locationId即可 defaultValue = locationId } ) ) { backStackEntry -> backStackEntry.arguments?.let { ManageOrders(locationId = it.getString(LOCATION_ID)!!) { orderId -> navController.navigate(LeafScreen.ManageOrderDetails.createRoute(root, orderId)) } } } }
内容的提问来源于stack exchange,提问作者Chandra Sekhar
相关产品推荐
相关产品推荐

