我正在开发 Jetpack Compose Navigation 演示,并且有一个嵌套导航图,其中包含两个不同的嵌套路线以及每个嵌套路线的屏幕:
登录图具有三种路线,用于显示三个不同的屏幕
- 路由“登录”以显示登录屏幕
- 路由“register”用于显示RegisterScreen
- 路由“recoverPassword”用于显示 RecoverPasswordScreen
主图有两个用于这些屏幕的路线
- 路由“home”以显示主屏幕
- 路由“设置”以显示设置屏幕
嵌套图的创建被称为MainActivity.kt
setContent {
NavigationDemoTheme {
val navController = rememberNavController()
SetupNavGraph(navController = navController)
}
}
文件中的函数嵌套导航图.kt看起来像这样:
fun SetupNavGraph(navController: NavHostController) {
NavHost(navController = navController, startDestination = "login_route")
{
loginGraph(navController = navController)
mainGraph(navController = navController)
}
}
在文件中LoginNavGraph.kt我已经定义了路线和出发目的地
fun NavGraphBuilder.loginGraph(navController: NavController) {
navigation(startDestination = "login", route = "login_route") {
composable(route = "login") {
LoginScreen(navController = navController)
}
composable(route = "register") {
RegisterScreen(navController = navController)
}
composable(route = "recover") {
RecoverPasswordScreen(navController = navController)
}
}
}
在文件中MainNavGraph.kt我已经定义了这两条路线和这个起始目的地:
navigation(startDestination = "home", route = "main_route") {
composable(route = "home") {
HomeScreen(navController = navController)
}
composable(route = "settings") {
SettingsScreen(navController = navController)
}
}
我现在的问题是:如何从设置屏幕显示恢复密码屏幕。我知道我可以从 SettingsScreen 导航到“login_route”,但随后将显示 startDestination,即 LoginScreen。
// shows the LoginScreen because the startDestination in the "login_route" is set to "login"
navController.navigate(route = "login_route")
那么,如何直接导航到嵌套图路由“login_route”中的路由“recover”?我想到了以下“解决方法”:
将参数传递给“login_route”,例如:
navController.navigate(route = "login_route?destination=recover")
然后,我将只有一条路线作为目的地,例如“LoginView”。这将改变登录图,如下所示:
fun NavGraphBuilder.loginGraph(navController: NavController) {
navigation(startDestination = "login_view, route = "login_route/{destination}) {
composable(
route = "login_view",
arguments = listOf(
navArgument("destination") { defaultValue = "login" },
)
) { backStackEntry ->
val destination = backStackEntry.arguments?.getString("destination");
destination?.let { destination ->
LoginView(destination = destination)
}
}
}
}
LoginView 是可组合的,它将有一个自己的 NavHost,我可以在其中使用上一个路由中的查询参数设置 startDestination:
fun LoginView( destination : String = "login"){
val navController = rememberNavController()
var startDestination = destination;
Scaffold ()
{
NavHost(
navController = navController,
startDestination = startDestination
) {
composable(route = "login") {
LoginScreen(navController = navController)
}
composable(route = "register") {
RegisterScreen(navController = navController)
}
composable(route = "recover") {
RecoverPasswordScreen(navController = navController)
}
}
}
现在我应该能够从设置屏幕调用 RecoverPasswordScreen:
navController.navigate(route = "login_route?destination=recover")
另一种可能性是在定义的 MainGraph 中为 RecoverPassword Screen 提供额外的路由。是否有其他可能性可以直接访问嵌套图中的路线?如果可以在路由到“login_route”时动态更改 startDestination 那就太好了,但我不知道如何或是否可能这样做。