NavHost的startDestination不接受序列化对象,仅支持字符串参数问题
你遇到的问题是因为Navigation Compose的类型安全路由底层依赖kotlinx-serialization的序列化名称匹配路由,但startDestination参数要求传入字符串类型,直接传序列化对象会触发类型错误。虽然Profile.toString()能临时生效,但这不是规范做法,以下是两种可靠的解决方式:
方式一:使用序列化描述符获取路由名称
利用kotlinx-serialization提供的序列化描述符,直接获取对象的官方路由名称,这是最贴合框架设计的做法:
@Serializable object Profile @Serializable object FriendsList val navController = rememberNavController() NavHost(navController = navController, startDestination = Profile.serializer().descriptor.serialName) { composable<Profile> { ProfileScreen(/* ... */) } composable<FriendsList> { FriendsListScreen(/* ... */) } // 添加更多目的地 }
方式二:自定义常量路由名称
给每个序列化对象定义明确的路由常量,提升代码可读性和可维护性:
@Serializable @SerialName("profile") // 可选:指定自定义序列化名称,和常量保持一致 object Profile { const val ROUTE = "profile" } @Serializable @SerialName("friends_list") object FriendsList { const val ROUTE = "friends_list" } val navController = rememberNavController() NavHost(navController = navController, startDestination = Profile.ROUTE) { composable<Profile>(route = Profile.ROUTE) { ProfileScreen(/* ... */) } composable<FriendsList>(route = FriendsList.ROUTE) { FriendsListScreen(/* ... */) } // 添加更多目的地 }
为什么不推荐用toString()?
默认情况下,Kotlin object的toString()返回类的全限定名,而kotlinx-serialization默认的序列化名称也是全限定名,所以刚好匹配。但如果你自定义了toString()方法,或者给对象添加了@SerialName注解指定自定义路由名,toString()的结果就会和实际路由名称不匹配,导致导航失效。
内容的提问来源于stack exchange,提问作者Prince Kumar
相关产品推荐
相关产品推荐

