Compose Navigation 2.4.0-alpha08如何传递Parcelable类型参数?
问题根源
Jetpack Compose Navigation 从 2.4.0-alpha08 版本开始,将 NavBackStackEntry 的 arguments 属性改为只读 val,禁止直接重写赋值,同时后续对原有 arguments 实例的修改也不会被导航组件同步识别,这就是你第二种写法拿不到参数的原因。
解决方案
这里提供两种适配方案,你可以根据自己的代码改动成本选择:
方案1:最小改动适配(沿用原有取参逻辑)
无需调整导航路由结构,只需要将原来读写 arguments 的逻辑换成读写 SavedStateHandle 即可,SavedStateHandle 是官方提供的专门用于栈实例存储自定义数据的读写容器:
- 修改跳转逻辑:
private fun navigateToPlanet(navController: NavHostController, planet: Planet) { navController.currentBackStackEntry?.savedStateHandle?.set("planet", planet) navController.navigate("details") }
- 修改详情页取参逻辑:
@Composable private fun NavigationComponent(navController: NavHostController) { NavHost(navController = navController, startDestination = "home") { composable("home") { HomeScreen(navController) } composable("details") { val planet = navController .previousBackStackEntry ?.savedStateHandle ?.get<Planet>("planet") planet?.let { DetailsScreen(it, navController) } } } }
方案2:官方推荐标准参数传递方式
直接通过导航路由携带参数,符合导航组件的设计规范,适配性更强:
- 调整路由声明,指定参数类型:
@Composable private fun NavigationComponent(navController: NavHostController) { NavHost(navController = navController, startDestination = "home") { composable("home") { HomeScreen(navController) } composable( route = "details/{planet}", arguments = listOf( navArgument("planet") { type = NavType.ParcelableType(Planet::class.java) } ) ) { backStackEntry -> val planet = backStackEntry.arguments?.getParcelable<Planet>("planet") planet?.let { DetailsScreen(it, navController) } } } }
- 修改跳转逻辑,直接将参数传入路由:
private fun navigateToPlanet(navController: NavHostController, planet: Planet) { navController.navigate("details/${planet}") }
内容的提问来源于stack exchange,提问作者Pierre Vieira
相关产品推荐
相关产品推荐

