You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:49:58