Jetpack Compose:嵌套导航,在嵌套路径中使用底部栏导航

xsh*_*ake 14 navigation bottombar android-jetpack-compose jetpack-compose-navigation

我的应用程序具有以下结构,并且由于路线 B ​​有自己的底部导航栏,因此有自己的 NavHost,因此我如何从屏幕 C(从选项卡栏打开)导航到路线 A?

 - Nested Route "/onboarding_route", startDestination = 'start' 
     - route 'start' -> Screen 'Login' (Composable)
     - route 'legal' -> Screen 'Legal' (Composable)

- Nested Route "/login_route", startDestination = 'login' 
     - route 'login' -> Screen 'Login' (Composable)
     - route 'register' -> Screen 'Register' (composable)
     - route 'recover' -> Screen 'Recover' (composable)

- Nested Route '/main_app', startDestination 'dashboard' => with bottom navigation
     - route 'dashboard' -> Screen 'Dashboard' (composable)
     - route 'product' -> Screen 'Product' (composable)
     - route 'profile' -> Screen 'Profile'
     
Run Code Online (Sandbox Code Playgroud)

导航到路线“main_app”应显示带有三个导航项的底部导航栏。我可以使用每个屏幕(仪表板、产品、配置文件)中带有底部栏的脚手架来完成此操作,或者我可以在顶部添加一个 MainView 屏幕,该屏幕固定带有底部栏的脚手架:

 - Nested Route '/main_app', startDestination 'mainVie/dashboard' => with bottom navigation
     - route 'mainView/{tabname} => Screen 'MainView' with Scaffold & bottom bar
          - route 'dashboard' -> Screen 'Dashboard' (composable)
          - route 'product' -> Screen 'Product' (composable)
          - route 'profile' -> Screen 'Profile'
Run Code Online (Sandbox Code Playgroud)

如果我使用此解决方案,则会遇到以下问题:在“仪表板”、“产品”和“配置文件”屏幕中,我只有底部栏中的导航控制器,并且无法导航到“login_route”等顶级路线。

我认为这是很常见的场景:你有一个入门屏幕、登录/注册屏幕,而且它们都没有底部栏。进入主屏幕后,您希望显示底部栏,然后您可能希望从其中一个屏幕返回登录屏幕。如果整个导航被分隔在嵌套导航路线中(正如谷歌建议的那样),我不知道如何从嵌套屏幕导航回最上面的路线之一。

拥有正确且简洁的导航结构的最佳实践是什么?

小智 1

首先,你有 mainActivity 和这个 navGraph :

AnimatedNavHost(
    navController = navController,
    startDestination = "onBoarding",
    modifier = modifier
) {
  onBoardingScreen(
   navigateToLegal = {
    navController.navigateToLegal()
   }
   nestedGraphs = {
      legalScreen()
   }
  )
  loginScreen(
   nestedGraphs = {
      registerScreen()
      recoverScreen()
   }
  )
  mainScreen(
   nestedGraphs = {
      productScreen()
      profileScreen()
   }
  )
}
Run Code Online (Sandbox Code Playgroud)

然后在每个屏幕中你可以有这样的东西:

fun NavGraphBuilder.onBoardingScreen(
    nestedGraphs: NavGraphBuilder.() -> Unit,
    navigateToLegal : () -> Unit
) {
   navigation(
       route = "onBoardingGraphRoutePattern",
       startDestination ="start"
   ) {
       composable(
           route ="start",
       ) {
        StartRoute()
       }
       nestedGraphs()
    }
}
Run Code Online (Sandbox Code Playgroud)

对于每个嵌套屏幕,我们有两个这样的函数:

1-

fun NavController.navigateToLegal(
   navOptions: NavOptions? = null
) {
   this.navigate("legal", navOptions)
}
Run Code Online (Sandbox Code Playgroud)

2-

fun NavGraphBuilder.legalScreen() {
  composable(
      route = "legal",
  ) {
      LegalRoute()
  }
}
Run Code Online (Sandbox Code Playgroud)

我认为通过这种模式,您可以在每个屏幕的主导航和嵌套导航图中拥有一个导航控制器,并且可以处理您的应用程序

有关更多信息和更多示例,您可以阅读此项目: Now In Android

希望对你有帮助:)