Search code examples
android-jetpack-composenavigationbarjetpack-compose-navigation

With Compose, how can I show a navigation bar only on a sub navigation graph


I'm making a Kotlin Multiplatform / Compose Multiplatform app. I want this sort of graph :

  • SplashScreen
  • AuthScreen
  • MainGraph
    • HomeScreen
    • ...
    • SettingsScreen

I want a navigation bar to navigate through my main graph, but obviously, I don't want to have this navigation bar when I'm on my SplashScreen or AuthScreen. I thought it would be easy but strangely I can't find any post asking this or anything in the documentation about that. And ChatGPT keeps giving me code that doesn't even work.

I've tried using another NavHost in a composable block but it won't work. Like that :

val navController = rememberNavController()
NavHost(
    navController = navController,
    startDestination = Destination.Splash
) {
    composable<Destination.Splash> {
        SplashScreenRoot()
    }
    composable<Destination.Auth> {
        AuthScreenRoot()
    }
    composable<Destination.Main> {
        // Add navigation here
        NavHost(
            navController = navController,
            startDestination = Destination.Main.Home
        ) {
            composable<Destination.Main.Home> {
                HomeScreenRoot()
            }
            composable<Destination.Main.Settings> {
                SettingsScreenRoot()
            }
        }
    }
}

I've seen a way to do this by having a nav bar and showing it depending on the current route but it seems weird that there wouldn't be a cleaner way to do this seeing as it is a pretty basic situation.


Solution

  • You can do it by setting a nested NavHost that contains navigation bar with a Scaffold.

    val navController = rememberNavController()
    NavHost(
        navController = navController,
        startDestination = Destination.Splash
    ) {
        composable<Destination.Splash> {
            SplashScreenRoot()
        }
        composable<Destination.Auth> {
            AuthScreenRoot()
        }
        composable<Destination.Main> {
            MainContainer()
           
        }
    }
    

    And MainContainer that contains nested NavHost with bottom navigation

    @Composable
    private fun MainContainer() {
    
        val nestedNavController = rememberNavController()
        Scaffold(
            modifier = Modifier.fillMaxSize(),
            bottomBar = {
                NavigationBar {
    
                }
            }
        ) { paddingValues: PaddingValues ->
            NavHost(
                modifier = Modifier.padding(paddingValues),
                navController = nestedNavController,
                startDestination = Destination.Main.Home
            ) {
                addBottomNavigationGraph()
            }
        }
    }
    

    You can check full sample in github repo.