Implementing Nested Navigation with Bottom Bar and Separate Navigation Graphs in Android Jetpack…
Introduction
Implementing Nested Navigation with Bottom Bar and Separate Navigation Graphs in Android Jetpack Compose
Introduction
In this article, I will delve into the intricacies of implementing nested navigation in Jetpack Compose. Recently tasked with enhancing the user experience of an Android App, I encountered various issues contributing to its bugginess. As I delved deeper into the investigation, it became apparent that the app, which encompassed multiple screens and diverse user flows (login, welcome section, and the main app flow), utilized a single navigation graph for the entire application. This architectural choice was identified as a source of bugs.
Conducting research online, I discovered that employing a shared navigation graph for distinct user flows could lead to performance issues. To address this challenge, I sought a solution that involved separating these flows, ultimately aiming to enhance the app’s speed and overall usability.
The remedy I found was the implementation of nested navigation. This article serves as a guide, detailing my approach to implementing this feature. It aims not only to share my experience but also to assist others facing similar challenges in their app development journey.
Alright, lets get started.
Getting Started.
In this article, we are going to create a simple app with nested navigation and 2 user flows.
First, this is going to be our app structure / User Flow

This is going to be our graph structure

With that out of the way, lets start the coding
- First Step
Create a new android jetpack compose project and add the following dependencies
//Navigation Dependency
implementation("androidx.navigation:navigation-compose:2.7.7")
//Material Dependecy Bottom Nav Bar
implementation("androidx.compose.material:material:1.6.2")
- Second Step
In this step, our focus is on establishing the navigation graphs for our project, which is designed to incorporate a total of six screens. To enhance the organization and structure, we will adopt a more systematic approach. First, we will craft a sealed class that consolidates all the routes corresponding to the screens and their respective navigation graphs..
sealed class ScreenRoutes(val route : String) {
//Screen Routes
data object StartScreen : ScreenRoutes("start_screen")
data object LoginScreen : ScreenRoutes("login_screen")
data object HomeScreen : ScreenRoutes("home_screen")
data object ScreenA : ScreenRoutes("screen_a")
data object ScreenB : ScreenRoutes("screen_b")
data object LogoutScreen : ScreenRoutes("logout_screen")
//Graph Routes
data object AuthNav : ScreenRoutes("AUTH_NAV_GRAPH")
data object HomeNav : ScreenRoutes("HOME_NAV_GRAPH")
}
Next, we will create the Nav Graphs.
Root Nav Graph
@Composable
fun RootNav() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = ScreenRoutes.AuthNav.route
) {
AuthNav(navController)
composable(route = ScreenRoutes.HomeNav.route){
HomeScreen(
logout = {
navController.navigate(ScreenRoutes.AuthNav.route) {
popUpTo(0){}
}
}
)
}
}
}
In the provided code snippet, we’ve defined a root nav composable encompassing both the HomeScreen and AuthNav. Within this structure, the HomeScreen integrates our Home Nav Graph along with the Bottom Navigation Bar. Additionally, the Home Screen features a logout function. Given that the HomeNavGraph utilizes a distinct NavController, we must implement a state hoisted functionality to manage the logout operation and facilitate navigation from the Home Nav Graph back to the AuthNav Graph.
Auth Nav Graph
fun NavGraphBuilder.AuthNav(
navController: NavHostController
) {
navigation(
startDestination = ScreenRoutes.StartScreen.route,
route = ScreenRoutes.AuthNav.route
){
composable(route = ScreenRoutes.StartScreen.route){
StartScreen(navController = navController)
}
composable(route = ScreenRoutes.LoginScreen.route){
LoginScreen(navController = navController)
}
}
}
Home Nav Graph
@Composable
fun HomeNavGraph(
navController: NavHostController,
logout: () -> Unit
) {
NavHost(
navController = navController,
route = ScreenRoutes.HomeNav.route,
startDestination = ScreenRoutes.ScreenA.route
) {
composable(route = ScreenRoutes.ScreenA.route){
ScreenA(navHostController = navController)
}
composable(route = ScreenRoutes.ScreenB.route){
ScreenB(navHostController = navController)
}
composable(route = ScreenRoutes.LogoutScreen.route){
LogoutScreen(navHostController = navController, logout = logout)
}
}
}
In the provided code snippet, we’ve established the HomeNavGraph, encompassing various screens related to the Home section. This Nav Graph requires the NavController and the logout function as parameters. The logout function is subsequently utilized within the LogoutScreen Composable, where the logout functionality is executed, involving navigation from the HomeNavGraph back to the AuthNavGraph.
Next We will Create the Home Screen that contains the HomeNavGraph
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable
fun HomeScreen(
logout: () -> Unit
) {
val items = mutableListOf(
BottomNavItems.HomeItem,
BottomNavItems.Profile
)
val navController = rememberNavController()
Scaffold(
bottomBar = {
BottomNavigation {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
items.forEach { item ->
BottomNavigationItem(
selected = currentDestination?.hierarchy?.any { it.route == item.route } == true,
onClick = {
navController.navigate(item.route) {
// Pop up to the start destination of the graph to
// avoid building up a large stack of destinations
// on the back stack as users select items
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
}
},
icon = {
Icon(
painter = painterResource(id = item.icon),
contentDescription = item.title,
)
},
label = { Text(text = item.title) }
)
}
}
}
) {
HomeNavGraph(
navController,
logout
)
}
}
Under the HomeScreen, we define a bottom Navigation bar and the HomeNavGraph which is responsible for handling navigation within the Home Screen.
That’s it. !!!!!!
Inorder to access the full project, check out the following link on github
Nice Coding…
메타데이터
- post_id
- 13c77a99e994
- slug
- implementing-nested-navigation-with-bottom-bar-and-separate-navigation-graphs-in-android-jetpack-13c77a99e994
- url
- https://medium.com/@kezzieleo/implementing-nested-navigation-with-bottom-bar-and-separate-navigation-graphs-in-android-jetpack-13c77a99e994
- canonical_url
- https://medium.com/@kezzieleo/implementing-nested-navigation-with-bottom-bar-and-separate-navigation-graphs-in-android-jetpack-13c77a99e994
- author_url
- https://medium.com/@kezzieleo
- status
- ok
- fetched_at
- 2026-08-02 05:07:27