5

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?

Andra
  • 1,282
  • 2
  • 11
  • 34
  • I have the same question and another issue with the nested navigation. I have similiar structure and because Route B has a own bottom navigation bar and thus an own NavHost, how can I navigate from Screen C (opened from the tab bar) to Route A? See also here: https://stackoverflow.com/questions/71423059/jetpack-compose-nested-navigation-with-bottom-bar-navigation-in-a-nested-route – xshake Mar 10 '22 at 14:50
  • I did some search again and found out some people are using multiple NavHost. See https://github.com/arefhosseini/compose-multi-navigation . However, I'm not sure if this is the best approach. – Andra Mar 10 '22 at 16:02
  • @Andra is correct, using multiple navhosts is not the recommended approach. That being said I am having a hard time coming up with a solution that has a scaffold/bottombar at an inner level using only one navhost – lostintranslation Jun 09 '22 at 20:15

1 Answers1

1

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

Aref
  • 746
  • 10
  • 27