简体   繁体   中英

Jetpack Compose nested navigation and BottomAppBar

I'm trying to use jetpack compose navigation, but I had a problem in understanding nested navigation and layout the scaffold.

I had an app screen structure like this

root
├─ A
├─ B <- Had a bottom navigation bar
│  ├─ C
│  ├─ D

and this is the rough specs

  • The root would be in the MainActivity and have a NavHost and scaffold.
  • The app bar in A and B would be different.
  • There would be a bottom nav bar in B, which can be used to navigate between C and D

I have been looking through the docs and StackOverflow, from what I get it is best to just put the scaffold outside of NavHost.

But, for my case how can I update the app bar in A and B it if I don't get an access to the scaffold inside A & B? I can only think to make a branching in the scaffold like the code below

Scaffold(
    scaffoldState = scaffoldState,
    topBar = {
        when {
            currentDestination?.parent?.route == "Home" -> {
                TopAppBar(
                    title = {
                        Text("Home")
                    },
                )
            }
            currentDestination?.route == "Other screen" -> {
                 ....
            }

Also I need an access scaffold state in A.

So what is the best approach to solve this kind of problem?

I had this issue with NavHost and nested navigation with multi Scaffold .

Here is my first solution:

The root has its own NavHost that contains 2 separate pages(A & B) and these pages have its own functionality.

If we consider page A is kind of single page like Splash Screen, we have a basic Scaffold component to it.

And if we consider page B is kind of multi pages with bottom navigation like Instagram, at the top level we should create a NavHost for that own page.

Here is our root:

sealed class RouteScreen(val route: String) {
    object A : RouteScreen("a")
    object B : RouteScreen("b")
}

@Composable
internal fun RootNavigation(
    modifier: Modifier = Modifier,
    appState: MultiNavigationAppState
) {
    NavHost(
        navController = appState.navController,
        startDestination = RouteScreen.A.route,
        modifier = modifier
    ) {
        addA(appState)
        addB(appState)
    }
}

private fun NavGraphBuilder.addA(
    appState: MultiNavigationAppState
) {
    composable(route = RouteScreen.A.route) {
        AScreen()
    }
}

private fun NavGraphBuilder.addB(
    appState: MultiNavigationAppState
) {
    composable(route = RouteScreen.B.route) {
        BScreen(appState)
    }
}

AScreen is a composable that you can use Scaffold in it.

BScreen is same as AScreen but you can create another NavHost for control tabs.

@Composable
fun BScreen(
    appState: MultiNavigationAppState
) {
    val mainState = rememberMainState()
    Scaffold(
        bottomBar = {...}
    ) {
        BNavigation(...)
    }
}

Actually it's not recommended to use one NavHost with nested navigation because if pages have tabs and its functions like Instagram, we get in trouble.

Second solution is that we can use multi fragment with own NavHost, but it's not all based on Composable` components.

As you mentioned I face this issue and you can get more help with this Github project

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM