DEEPAKSINGH
3 min readJul 12, 2024

Bottom navigation bar in Android jetpack compose using material 3

Bottom navigation is a fundamental component in many mobile applications, allowing users to quickly switch between top-level views or destinations. In Jetpack Compose, implementing bottom navigation is straightforward and can be done using the NavigationBar and NavigationBarItem composables.

Android basic component - bottom navigation bar

Here’s a concise guide to creating a bottom navigation bar in Jetpack Compose:

1. Setup Dependencies
Ensure you have the necessary dependencies in your build.gradle file:

dependencies {
val nav_version = "2.7.7"
implementation("androidx.navigation:navigation-compose:$nav_version")
implementation "androidx.compose.material3:material3:$material3_version"
}

2. Create all screens for bottom navigation

@Composable
fun HomeScreen(navController: NavHostController) {
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
Text("Home Screen")
}
}
@Composable
fun SettingScreen(navController: NavHostController) {
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
Text("Setting Screen")
}
}
@Composable
fun ProfileScreen(navController: NavHostController) {
Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) {
Text("Profile Screen")
}
}

3. Define Navigation Destinations
Create a sealed class or enum to define the different destinations for the bottom navigation.

sealed class Screen(val route: String, val label: String, val icon: ImageVector) {
object Profile : Screen("profile", "profile", Icons.Filled.Profile)
object Home : Screen("home", "home", Icons.Filled.Home)
object Setting : Screen("setting", "setting", Icons.Filled.Setting)
}

This items list is used by NavigationBarItem Composable.

val items = listOf(
   Screen.Profile,
   Screen.Home,
Screen.Setting
)

4. Mainscreen.kt file is created , which hold bottom navigation bar

@Composable
fun MainScreen(navController: NavHostController){

val items = listOf(
   Screen.Profile,
   Screen.Home,
Screen.Setting
)
Scaffold(
  bottomBar = {
    NavigationBar {
      val navBackStackEntry by navController.currentBackStackEntryAsState()
      val currentDestination = navBackStackEntry?.destination
      items.forEach { screen ->
        NavigationBarItem(
          icon = { Icon(Icons.Filled.Favorite, contentDescription = null) },
          label = { Text(stringResource(screen.resourceId)) },
          selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
          onClick = {
            navController.navigate(screen.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
            }
          }
        )
      }
    }
  }
) { innerPadding ->

// NavigationGraph(modifier: Modifier = Modifier.padding(innerPadding), navController)
// or
  NavHost(navController, startDestination = Screen.Home.route, Modifier.padding(innerPadding)) {
    composable(Screen.Profile.route) { ProfileScreen(navController) }
    composable(Screen.Home.route) { HomeScreen(navController) }
composable(Screen.Setting.route) { SettingScreen(navController) }
  }
}


}

5. Inside MainActivity class, we simply call our MainScreen.kt.

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {

val navController = rememberNavController()

MainScreen(navController)


}
}
}

You have choose Graph directly defined in MainScreen.kt or create a separate file just like NagivationGraph.kt.

@Composable
fun NavigationGraph(modifier: Modifier, navController: NavHostController) {
NavHost(navController, startDestination = Screen.Home.route) {
composable(Screen.Home.route) { HomeScreen() }
composable(Screen.Search.route) { SettingScreen() }
composable(Screen.Profile.route) { ProfileScreen() }
}
}

Conclusion

This setup provides a basic bottom navigation implementation in Jetpack Compose, allowing for smooth and efficient navigation between top-level screens in your application.

That’s all Guys.