Compose导航:如何向嵌套导航图的起始目标传递参数?
当给Jetpack Compose嵌套导航图的起始目标传递参数时,直接在导航图路由后拼接参数仅对NavType.StringType有效,使用IntType会触发如下崩溃:
java.lang.IllegalArgumentException: Wrong argument type for 'intArgument' in argument bundle. integer expected.
问题代码分析
原代码中,参数仅在起始目标的composable中声明类型,跳转时未正确传递参数到嵌套导航图:
private const val featureGraphRoute = "feature_graph" private const val firstRouteArg = "intArgument" private const val firstRoute = "first_route/{$firstRouteArg}" private const val secondRoute = "second_route" fun NavController.navigateToFeatureGraph(argument:Int, navOptions: NavOptions? = null) { //TODO: pass the argument this.navigate(featureGraphRoute, navOptions) } fun NavGraphBuilder.featureGraph() { navigation( route = featureGraphRoute, startDestination = firstRoute ) { composable( route = firstRoute, arguments = listOf( navArgument(firstRouteArg){ type = NavType.IntType } ) ) { backStackEntry -> FirstRoute( argument = backStackEntry.arguments?.getInt(firstRouteArg) ) } composable(route = firstRoute) { // 此处为笔误,应为secondRoute SecondRoute() } } }
正确解决方案
核心是利用NavGraphBuilder.navigation的arguments重载,将参数类型声明上移到嵌套导航图级别,让导航系统正确识别参数类型,同时修改路由和跳转逻辑传递参数:
private const val firstRouteArg = "intArgument" // 给嵌套导航图路由添加参数占位符 private const val featureGraphRoute = "feature_graph/{$firstRouteArg}" private const val firstRoute = "first_route" private const val secondRoute = "second_route" fun NavController.navigateToFeatureGraph(argument: Int, navOptions: NavOptions? = null) { // 拼接参数到导航图路由中 val targetRoute = featureGraphRoute.replace("{$firstRouteArg}", argument.toString()) this.navigate(targetRoute, navOptions) } fun NavGraphBuilder.featureGraph() { navigation( route = featureGraphRoute, startDestination = firstRoute, // 在导航图级别声明参数类型 arguments = listOf( navArgument(firstRouteArg) { type = NavType.IntType } ) ) { composable(route = firstRoute) { backStackEntry -> // 从导航图的回退栈中获取参数 val argument = backStackEntry.arguments?.getInt(firstRouteArg) FirstRoute(argument = argument) } composable(route = secondRoute) { SecondRoute() } } }
关键说明
嵌套导航图的起始目标会自动继承导航图本身的参数,因此将参数类型声明在导航图级别后,导航系统会正确解析参数类型,避免类型不匹配的崩溃。起始目标的路由无需再包含参数占位符,直接从导航图的backStackEntry中读取参数即可。
内容的提问来源于stack exchange,提问作者puny
相关产品推荐
相关产品推荐

