在Jetpack Compose的类型安全导航(Navigation 2.8.0及以上)中,如何传递自定义Parcelable对象?
随着Jetpack Compose Navigation 2.8.0的发布,我们现在可以使用类型安全的对象(@Serializable 数据类)来进行导航,而不是路由字符串。
然而,如果我的路由数据类包含一个自定义的 Parcelable 对象,导航组件默认并不知道如何处理它。
例如,我为我的路由定义了一个密封类:
@Serializable
sealed class Route {
@Serializable
data class DetailsScreen(val userData: UserData) : Route()
}
其中 UserData 是一个 @Parcelize 类。如何为这个 Parcelable 对象定义并注册一个自定义的 NavType,以便在新的Compose导航图中安全地传递它?
解决方案
新的类型安全导航(2.8.0)很不错,但它原生并不能直接处理 Parcelable 对象,这有点让人恼火。你必须手动定义一个自定义的 NavType,因为库不知道如何将你的自定义类序列化成路由字符串。
下面是使用 kotlinx.serialization 的最简洁方法。
首先为你的对象创建一个Nav类型。
使用这个通用辅助工具来处理JSON的编码和解码。 例如
val UserDataNavType = object : NavType<UserData>(isNullableAllowed = false) {
override fun get(bundle: Bundle, key: String): UserData? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
bundle.getParcelable(key, UserData::class.java)
} else {
@Suppress("DEPRECATION")
bundle.getParcelable(key)
}
}
override fun parseValue(value: String): UserData {
return Json.decodeFromString(value)
}
override fun put(bundle: Bundle, key: String, value: UserData) {
bundle.putParcelable(key, value)
}
override fun serializeAsValue(value: UserData): String {
return Uri.encode(Json.encodeToString(value))
}
}
现在把它传给你的Nav控制器
在定义你的 composable 目标时,必须在 typeMap 注册这个类型。
composable<Route.Details>(
typeMap = mapOf(typeOf<UserData>() to UserDataNavType)
) { backStackEntry ->
val details = backStackEntry.toRoute<Route.Details>()
DetailScreen(details.userData)
}
现在你可以在Navigate中正常传递对象。
navController.navigate(Route.Details(myUserObject))
重要! 确保 UserData 类同时被 @Parcelize 与 @Serializable 这两个注解标注。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。