【发布时间】: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