4

I'm developing an android application using Jetpack Compose. For now, I have several screens (Login, Register, Messages, Profile and Settings). I used a root NavGraph to host the navGraphs of authentication and main screen (See the codes below).

RootNavGraph.kt

@Composable
fun RootNavGraph(navController: NavHostController) {
NavHost(
        navController = navController,
        startDestination = AUTHENTICATION_ROUTE,
        route = ROOT_ROUTE
    ) {
        authNavGraph(navController = navController)
        bottomNavGraph(navController = navController)
    }
}

authNavGraph.kt

fun NavGraphBuilder.authNavGraph(navController: NavHostController) {

    navigation(
        startDestination = AuthenticationScreens.Login.route,
        route = AUTHENTICATION_ROUTE
    ) {
        composable(route = AuthenticationScreens.Login.route) {
            LoginPage(navController = navController)
        }
        composable(route = AuthenticationScreens.Register.route) {
            RegisterPage(navController = navController)
        }
    }
}

bottomNavGraph.kt

fun NavGraphBuilder.bottomNavGraph(navController: NavHostController) {
    navigation(
        startDestination = BottomBarScreen.Messages.route,
        route = BOTTOM_ROOT_ROUTE
    ) {

        composable(route = BottomBarScreen.Messages.route) {
            Messages()
        }
        composable(route = BottomBarScreen.Profile.route) {
            Profile(navController = navController)
        }
        composable(route = BottomBarScreen.Settings.route) {
            Settings()
        }
    }
}

I have the MainScreen that contains the bottom navigation bar.

@Composable
fun MainScreen() {

    val navController = rememberNavController()
    Scaffold(
        bottomBar = {
            BottomBar(navController = navController)
        }
    ) {
//bottomNavGraph(navController)
    }
}

@Composable
fun BottomBar(navController: NavHostController) {

    val screens = listOf(
        BottomBarScreen.Messages,
        BottomBarScreen.Profile,
        BottomBarScreen.Settings
    )
    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentDestination = navBackStackEntry?.destination

    BottomNavigation() {
        screens.forEach { screen ->
            AddItem(
                screen = screen,
                currentDestination = currentDestination,
                navController = navController
            )
        }
    }
}

@Composable
fun RowScope.AddItem(
    screen: BottomBarScreen,
    currentDestination: NavDestination?,
    navController: NavHostController
) {

    BottomNavigationItem(
        label = {
            Text(text = screen.title)
        },
        alwaysShowLabel = false,
        icon = {
            Icon(imageVector = screen.icon, contentDescription = "Navigation Icon")
        },
        selected = currentDestination?.hierarchy?.any {
            it.route == screen.route
        } == true,
        unselectedContentColor = LocalContentColor.current.copy(alpha = ContentAlpha.disabled),
        onClick = {
            navController.navigate(screen.route) {
                popUpTo(navController.graph.findStartDestination().id)
                launchSingleTop = true
            }
        }
    )
}

My problem is: after switching to use the nested nav graphs, I cannot use the bottomNavGraph directly in the MainScreen since it's no longer a NavHost and thus the bottom navigation bar isn't showing. I would appreciate if any one can help me with that.

1 Answers1

0

For bottom navigation use the NavHost to show the bottom bar

fun HomeNavGraph(navHostController: NavHostController) {
    NavHost(
        navController = navHostController,
        route = Graph.Home,
        startDestination = BottomBar.Home.route
    ) {
        composable(BottomBar.Home.route){
            HomeScreenContent()
        }

then use this graph in your homescreen scaffold

fun HomeScreen(navController: NavHostController = rememberNavController()) {
    Scaffold(bottomBar = {
        BottomNavigation(navController = navController)
    }) {
        HomeNavGraph(navHostController = navController)
    }

at last in the rootgraph use this homescreen class with your rootgraph route

fun RootNavigationGraphBuilder(navHostController: NavHostController) {
    NavHost(navController = navHostController, startDestination = Graph.Authentication, route = Graph.Root) {
        authNavGraph(navHostController)
        composable(route = Graph.Home){
            HomeScreen()
        }
    }

here are sample routes which i use in my code

object Graph {
    const val Root = "root_graph"
    const val Authentication = "auth_graph"
    const val Home = "home_graph"

}