渐进式编程课
KMP 目录
第 27 课2026.08.12

从列表页打开详情页时,通常需要告诉详情页“打开哪一条数据”。把 id 放进路由后,Android 与 iOS 共用同一种参数格式,编译器也能检查参数类型。

第 27 课:Compose 类型安全路由传参

知识点

使用可序列化的 data class 路由,在 Compose Multiplatform 页面之间传递类型安全参数。

用途

从列表页打开详情页时,通常需要告诉详情页“打开哪一条数据”。把 id 放进路由后,Android 与 iOS 共用同一种参数格式,编译器也能检查参数类型。

核心概念

  • 无参数路由适合使用 object,带参数路由使用 data class。
  • 路由类型必须标记 @Serializable。
  • 跳转时传入路由实例,例如 Detail(itemId = 42)。
  • 目标页面通过 backStackEntry.toRoute<Detail>() 还原参数。
  • 路由只传最小标识,如 itemId;完整对象应由详情页根据 ID 从数据层读取。

示例代码

kotlin
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.navigation.toRoute
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import kotlinx.serialization.Serializable

@Serializable
data object Home

@Serializable
data class Detail(val itemId: Long)

@Composable
fun App() {
    val navController = rememberNavController()

    NavHost(
        navController = navController,
        startDestination = Home,
    ) {
        composable<Home> {
            Button(
                onClick = {
                    navController.navigate(Detail(itemId = 42L))
                },
            ) {
                Text("查看第 42 条数据")
            }
        }

        composable<Detail> { backStackEntry ->
            val route = backStackEntry.toRoute<Detail>()
            Text("当前数据 ID:${route.itemId}")
        }
    }
}

这里若误写成 Detail(itemId = "42"),编译阶段就会报类型错误。

5 分钟练习

新增一个用户详情路由 UserDetail,接收字符串类型的 userId。点击首页按钮时传入 "user-100",并在目标页显示该 ID。

参考答案

kotlin
@Serializable
data class UserDetail(val userId: String)

// 首页按钮
Button(
    onClick = {
        navController.navigate(UserDetail(userId = "user-100"))
    },
) {
    Text("查看用户")
}

// NavHost 中的目标页
composable<UserDetail> { backStackEntry ->
    val route = backStackEntry.toRoute<UserDetail>()
    Text("用户 ID:${route.userId}")
}

与上一课的联系

上一课用无参数 Home、Detail 路由完成了页面跳转;今天把 Detail 升级为带 itemId 的路由,让目标页知道应加载哪一条数据。

参考资料