【问题标题】:How to pass Arguments between Nested Navigation Graph Jet Compose如何在嵌套导航图 Jet Compose 之间传递参数
【发布时间】:2023-01-20 06:12:58
【问题描述】:

我想将 {id} 从 ListScreen 传递到 DetailScreen。在 ListScreen 中,当点击事件发生时,我开始像这样导航到 DetailScreen。

navController.navigate(
                        route = AppDestination.UserProfile.passId(
                            friendId = it.friendId
                        )
                    )

在 DetailScreen 中,我通过这样的构造函数获取 friendId。

@Composable
fun UserProfileScreen(
    navController: NavController,
    friendId: Long,
) {
    UserProfileView(
        navController = navController,
        friendId = friendId
    )
}

在我的应用程序中,我只使用 3 个图表管理导航流程。像 RootGraph、AuthGraph 和 HomeGraph。以下是导航代码。

object Routes {
    const val AUTH_ROUTE = "auth"
    const val HOME_ROUTE = "home"
    const val ROOT_ROUTE = "root"
}

object ArgsConstants{
    const val USER_PROFILE_KEY = "id"
}

sealed class AppDestination(val route: String) {
 //user
    object UserProfile : AppDestination(route = "user_profile_screen/{${ArgsConstants.USER_PROFILE_KEY}}"){
        fun passId(friendId : Long): String{

            return this.route.replace(
                oldValue = "{${ArgsConstants.USER_PROFILE_KEY}}",
                newValue = friendId.toString()
            )
        }
    }
}

这是我的 RootGraph。

@Composable
fun RootNavGraph(
    navController: NavHostController
) {
    NavHost(
        navController = navController,
        startDestination = AppDestination.Branding.route,
        route = Routes.ROOT_ROUTE
    ) {
        composable(route = AppDestination.Branding.route) {
            BrandingScreen(navController = navController)
        }

        authNavGraph(navController = navController)
        homeNavGraph(navController = navController)

    }
}

这是我的 AuthGraph。

fun NavGraphBuilder.authNavGraph(
    navController: NavHostController
) {
    navigation(
        startDestination = AppDestination.Language.route,
        route = Routes.AUTH_ROUTE
    ) {

        composable(route = AppDestination.Language.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            LanguageScreen(navController = navController, vm = authViewModel)
        }

        composable(route = AppDestination.Login.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            LoginScreen(navController = navController, vm = authViewModel)
        }

        composable(route = AppDestination.Signup.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            SignupScreen(navController = navController, vm = authViewModel)
        }

        composable(route = AppDestination.VerifiedAccount.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            VerifiedAccountScreen(navController = navController, vm = authViewModel)
        }
        composable(route = AppDestination.NoAccount.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            NoAccountScreen(navController = navController, vm = authViewModel)
        }
        composable(route = AppDestination.VerifiedMethod.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            VerifiedMethodScreen(navController = navController, vm = authViewModel)
        }
        composable(route = AppDestination.VerifiedOtp.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            VerifiedOtpScreen(navController = navController, vm = authViewModel)
        }
        composable(route = AppDestination.VerifiedQuestion.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            VerifiedQuestionScreen(navController = navController, vm = authViewModel)
        }
        composable(route = AppDestination.TwoFactor.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            TwoFactorScreen(navController = navController, vm = authViewModel)
        }

        composable(route = AppDestination.PasswordReset.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            PasswordResetScreen(navController = navController, vm = authViewModel)
        }

        composable(route = AppDestination.SuccessReset.route) {
            val parentEntry = remember {
                navController.getBackStackEntry(Routes.AUTH_ROUTE)
            }
            val authViewModel = hiltViewModel<AuthViewModel>(parentEntry)

            SuccessResetScreen(navController = navController, vm = authViewModel)
        }

    }
}

这是我的 HomeGraph。

fun NavGraphBuilder.homeNavGraph(
    navController: NavHostController
) {
    navigation(
        startDestination = AppDestination.Home.route,
        route = Routes.HOME_ROUTE
    ) {
 //user
        composable(route = AppDestination.UserProfile.route + "/{${ArgsConstants.USER_PROFILE_KEY}}",
            arguments = listOf(
                navArgument(
                    name = ArgsConstants.USER_PROFILE_KEY,
                ) {
                    type = NavType.LongType
                }
            )) {

            Timber.tag("ahahah").d(it.arguments?.getLong(ArgsConstants.USER_PROFILE_KEY).toString())
            UserProfileScreen(
                navController = navController,
                friendId = it.arguments?.getLong(ArgsConstants.USER_PROFILE_KEY) ?: -1L
            )
        }
    }
}

这是我在启动导航路线时的错误。

 java.lang.IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/user_profile_screen/1084 } cannot be found in the navigation graph NavGraph(0x78dcd1ef) route=root startDestination={Destination(0xf2da2703) route=branding_screen}

我在其他项目中实现了导航参数,但在这个项目中,我管理 3 个图表。我想我的失败就是因为这个。我尝试了其他方式,例如在 ViewModel 中与 saveStateHandle 共享。也失败了。请帮我。我坚持了一周。

【问题讨论】:

  • 你修好了吗?否则,您能否提供最低限度的可重现代码?快速看一下,我想你忘了在你的可组合项中声明 deeplink 参数......看看这个:developer.android.com/jetpack/compose/navigation#deeplinks
  • 是的。我今天修好了这个。这是我的愚蠢。只是一个错字。太有趣了。感谢您的帮助。

标签: android navigation android-jetpack-compose jetpack-compose-navigation


【解决方案1】:

你可以帮帮我吗?我正在处理像你这样的问题,但我找不到答案。

【讨论】:

  • Manos Brsls,请不要添加我也是作为答案。它实际上并没有提供问题的答案。如果您有不同但相关的问题,请ask它(如果它有助于提供上下文,请参考此问题)。如果你对这个具体问题感兴趣,你可以upvote它,留下comment,或者一旦你有足够的reputation就开始bounty
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 2022-09-30
  • 2018-04-09
  • 1970-01-01
  • 2022-11-11
相关资源
最近更新 更多