Jetpack Compose带参数导航崩溃:IllegalArgumentException异常解决
Jetpack Compose导航崩溃问题解决:枚举类转密封类
问题重现
最初我用枚举类管理页面路由:
enum class AppScreen(@StringRes val title: Int) { Index(title = R.string.app_name), Detail(title = R.string.app_name) }
并编写了对应的Composable导航逻辑:
composable(route = AppScreen.Index.name){ IndexScreen( onNavigate = { id -> Log.d(TAG, "id: " + id.toString()) navController.navigate( route = "${AppScreen.Detail.name}?id=$id", ) } ) } composable( route = "${AppScreen.Detail.name}/{id}", arguments = listOf( navArgument("id") { type = NavType.IntType } ) ){ val id = it.arguments?.getInt("id") ?: -1 DetailScreen(id) }
点击Index页面的列表项时,日志能正常打印item的id,但随后应用崩溃,抛出错误:
java.lang.IllegalArgumentException: No enum constant com.utils.AppScreen.Detail/{id}
问题原因
枚举类的name属性仅返回枚举常量的纯名称(如Detail),但我们在定义Detail页面路由时拼接了/{id}。当导航系统尝试将带参数占位符的路由字符串映射回枚举时,找不到匹配的枚举常量,从而触发崩溃。
解决方案:改用密封类管理路由
将枚举类替换为密封类,直接在类中定义完整路由,并为带参数的页面提供路由生成方法:
sealed class AppScreen( val route: String, @StringRes val title: Int ) { object Index: AppScreen("Index", R.string.index) object Detail: AppScreen("Detail/{id}", R.string.detail) { fun createRoute(id: Int) ="Detail/$id" } }
然后修改导航逻辑,直接使用密封类中定义的路由:
composable(route = AppScreen.Index.route){ IndexScreen( onNavigate = { id -> navController.navigate( route = AppScreen.Detail.createRoute(id), ) } ) } composable( route = AppScreen.Detail.route, arguments = listOf( navArgument("id") { type = NavType.IntType } ) ){ val id = it.arguments?.getInt("id") ?: -1 DetailScreen(id) }
这种方式既统一了路由定义,避免手动拼接字符串的错误,也完美适配了带参数的路由场景。
内容的提问来源于stack exchange,提问作者sara
相关产品推荐
相关产品推荐

