在 Compose 中使用 SavedStateHandle 传递整数导航参数时发生投射错误
Cast Error on passing Integer Nav Argument using SavedStateHandle in Compose
我正在尝试从第一个屏幕导航到第二个屏幕,我需要提供一个整数标识符以在第二个屏幕上从 API 加载内容。
我在尝试传递 Int Nav 参数时 运行 遇到了这个错误。
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
这是我的 NavHost,我在其中使用 /{recipeId}
作为第二个屏幕路线上的占位符。
NavHost(
navController = navController,
startDestination = Screens.RecipesOverviewScreen.route
) {
//1st Screen
composable(route = Screens.RecipesOverviewScreen.route) {
RecipesOverviewScreen(
navController = navController,
onToggleTheme = { app.toggleLightTheme() })
}
//2nd Screen
composable(route = "${Screens.RecipeDetailScreen.route}/{recipeId}")
{
RecipeDetailScreen()
}
然后我在第一个屏幕中调用 navController.navigate()
,将 Int 类型的 id
传入导航路线。
RecipeList(recipes = listState.recipes,
onClickRecipeCard = { id ->
//insert corresponding Int id into the Nav route
navController.navigate(
route = "${Screens.RecipeDetailScreen.route}/${id}"
)
}
在第二个屏幕的 ViewModel 中,我使用 SavedHandleInstance 检索导航参数。
@HiltViewModel
class RecipeViewModel @Inject constructor(
savedStateHandle: SavedStateHandle
) : ViewModel() {
init {
//pass in the key inside get() fxn
savedStateHandle.get<Int>(Constants.PARAM_RECIPE_ID)
?.let { id ->
//perform an API call inside init{} using nav arg id
getRecipe(id = id, token = token)
} ....}
此时,应用程序崩溃了,我得到了上面的 logcat 输出。
请在传递 Int Nav arg 时为我指出正确的方向。
当您将第二个屏幕定义为:
composable(route = "${Screens.RecipeDetailScreen.route}/{recipeId}") {
您没有为 recipeId
参数定义任何类型。根据 Navigate with arguments guide:
By default, all arguments are parsed as strings. You can specify another type by using the arguments
parameter to set a type
因此,如果您希望 recipeId
成为 Int
,则必须将其声明为 IntType
:
composable(
route = "${Screens.RecipeDetailScreen.route}/{recipeId}",
arguments = listOf(navArgument("recipeId") { type = NavType.IntType })
) {
这将确保您对 savedStateHandle.get<Int>
的调用实际上有一个要查找的 Int
,而不是 String
。
我正在尝试从第一个屏幕导航到第二个屏幕,我需要提供一个整数标识符以在第二个屏幕上从 API 加载内容。
我在尝试传递 Int Nav 参数时 运行 遇到了这个错误。
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
这是我的 NavHost,我在其中使用 /{recipeId}
作为第二个屏幕路线上的占位符。
NavHost(
navController = navController,
startDestination = Screens.RecipesOverviewScreen.route
) {
//1st Screen
composable(route = Screens.RecipesOverviewScreen.route) {
RecipesOverviewScreen(
navController = navController,
onToggleTheme = { app.toggleLightTheme() })
}
//2nd Screen
composable(route = "${Screens.RecipeDetailScreen.route}/{recipeId}")
{
RecipeDetailScreen()
}
然后我在第一个屏幕中调用 navController.navigate()
,将 Int 类型的 id
传入导航路线。
RecipeList(recipes = listState.recipes,
onClickRecipeCard = { id ->
//insert corresponding Int id into the Nav route
navController.navigate(
route = "${Screens.RecipeDetailScreen.route}/${id}"
)
}
在第二个屏幕的 ViewModel 中,我使用 SavedHandleInstance 检索导航参数。
@HiltViewModel
class RecipeViewModel @Inject constructor(
savedStateHandle: SavedStateHandle
) : ViewModel() {
init {
//pass in the key inside get() fxn
savedStateHandle.get<Int>(Constants.PARAM_RECIPE_ID)
?.let { id ->
//perform an API call inside init{} using nav arg id
getRecipe(id = id, token = token)
} ....}
此时,应用程序崩溃了,我得到了上面的 logcat 输出。
请在传递 Int Nav arg 时为我指出正确的方向。
当您将第二个屏幕定义为:
composable(route = "${Screens.RecipeDetailScreen.route}/{recipeId}") {
您没有为 recipeId
参数定义任何类型。根据 Navigate with arguments guide:
By default, all arguments are parsed as strings. You can specify another type by using the
arguments
parameter to set atype
因此,如果您希望 recipeId
成为 Int
,则必须将其声明为 IntType
:
composable(
route = "${Screens.RecipeDetailScreen.route}/{recipeId}",
arguments = listOf(navArgument("recipeId") { type = NavType.IntType })
) {
这将确保您对 savedStateHandle.get<Int>
的调用实际上有一个要查找的 Int
,而不是 String
。