Bottom Navigation Bar with Jetpack Compose

Photo by Axel Antas-Bergkvist on Unsplash

Note: You need to have Android Studio Arctic Fox to use Jetpack Compose in your project.

Adding libraries

Open your project-level build.gradle file, and add the following extension:

buildscript {
ext {
compose_version = '1.0.0-beta08'
}
//....
}

Open your app-level build.gradle file, and add the following

android {
//..
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerVersion '1.5.10'
}
}
dependencies {

implementation "androidx.compose.ui:ui:$compose_version"
implementation androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.0-beta01'
implementation "androidx.navigation:navigation-runtime-ktx:2.4.0- alpha02@aar"
implementation "androidx.navigation:navigation-compose:2.4.0-alpha02"

}

Now create the TopBar and Bottom Navigation Bar

TopBar

In your compose activity, add the following code outside the main class. We have used TopAppBar composable function and set the title, background color and content color.

@Composable
fun TopBar() {
TopAppBar(
title = { Text(text = stringResource(R.string.app_name), fontSize = 18.sp) },
backgroundColor = colorResource(id = R.color.teal_700),
contentColor = Color.White
)
}

Bottom Navigation Bar

To add Bottom Navigation Bar, we first need to think about the tabs in it. To show tabs, we will create a sealed class BottomNavigationItem with different options.

Create sealed class as follows.

sealed class BottomNavigationItem(var route: String, var icon: Int, var title: String) {
object One : BottomNavigationItem("one", android.R.drawable.ic_media_play, "One")
object Two : BottomNavigationItem("two", android.R.drawable.ic_media_play, "Two")
object Three : BottomNavigationItem("three", android.R.drawable.ic_media_play, "Three")
object Four : BottomNavigationItem("four", android.R.drawable.ic_media_play, "Four")
object Five : BottomNavigationItem("five", android.R.drawable.ic_media_play, "Five")
}

Next, similar to TopAppBar, add following code outside of your main class.

@Composable
fun BottomNavigationBar() {
val items = listOf(
BottomNavigationItem.One,
BottomNavigationItem.Two,
BottomNavigationItem.Three,
BottomNavigationItem.Four,
BottomNavigationItem.Five
)
BottomNavigation(
backgroundColor = colorResource(id = R.color.teal_700),
contentColor = Color.White
) {

items.forEach { item ->
BottomNavigationItem(
icon = { Icon(painterResource(id = item.icon), contentDescription = item.title) },
label = { Text(text = item.title) },
selectedContentColor = Color.White,
unselectedContentColor = Color.White.copy(0.4f),
alwaysShowLabel = true,
selected = false,
onClick = {
//...

}
}
)
}
}
}

As we have created the composable functions for TopAppBar and BottomNaviagionBar. Now its time to put them together. Add following composable function outside the main class.

@Composable
fun MainScreen() {
Scaffold(
topBar = { TopBar() },
bottomBar = { BottomNavigationBar(navController) }
)
}

Now, its time to create screens for different tabs in BottomNavigationBar

To create the screens, create a file and add following composable functions in it. Here we have FirstScreen, SecondScreen, ThirdScreen, FourthScreen, FifthScreen composable functions.

@Composable
fun FirstScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.wrapContentSize(Alignment.Center)
) {
Text(
text = "First View",
fontWeight = FontWeight.Bold,
color = Color.Black,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}


@Composable
fun SecondScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.wrapContentSize(Alignment.Center)
) {
Text(
text = "Second View",
fontWeight = FontWeight.Bold,
color = Color.Black,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}

@Composable
fun ThirdScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.wrapContentSize(Alignment.Center)
) {
Text(
text = "Third View",
fontWeight = FontWeight.Bold,
color = Color.Black,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}

@Composable
fun FourthScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.wrapContentSize(Alignment.Center)
) {
Text(
text = "Fourth View",
fontWeight = FontWeight.Bold,
color = Color.Black,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}

@Composable
fun FifthScreen() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
.wrapContentSize(Alignment.Center)
) {
Text(
text = "Fifth View",
fontWeight = FontWeight.Bold,
color = Color.Black,
modifier = Modifier.align(Alignment.CenterHorizontally),
textAlign = TextAlign.Center,
fontSize = 25.sp
)
}
}

To attach above created screens with BottomNavigationBar, first create the following composable function Navigate. It takes two parameters, NavHostController and route(String). NavHost is a NavGraphBuilder.

@Composable
fun Navigation(navController: NavHostController, route: String) {
NavHost(navController = navController, startDestination = route) {
composable(BottomNavigationItem.One.route) {
FirstScreen()
}
composable(BottomNavigationItem.Two.route) {
SecondScreen()
}
composable(BottomNavigationItem.Three.route) {
ThirdScreen()
}
composable(BottomNavigationItem.Four.route) {
FourthScreen()
}
composable(BottomNavigationItem.Five.route) {
FifthScreen()
}

}
}

In the MainScreen(), we create the Navigation Controller, and we’re passing it to the BottomNavigationBar and Navigation created above.

@Composable
fun MainScreen() {
val navController = rememberNavController()
Scaffold(
topBar = { TopBar() },
bottomBar = { BottomNavigationBar(navController) }
) {
Navigation(navController = navController, BottomNavigationItem.One.route)

}
}

Next, in the BottomNavigationBar, add the parameter navController, and create the navBackStackEntry and the currentRoute.

Using the currentRoute, we check if we have to highlight the bar item or not, and we navigate to the view using the navigate() method

@Composable
fun BottomNavigationBar(navController: NavController) {
val items = listOf(
BottomNavigationItem.One,
BottomNavigationItem.Two,
BottomNavigationItem.Three,
BottomNavigationItem.Four,
BottomNavigationItem.Five
)
BottomNavigation(
backgroundColor = colorResource(id = R.color.teal_700),
contentColor = Color.White
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route

items.forEach { item ->
BottomNavigationItem(
icon = { Icon(painterResource(id = item.icon), contentDescription = item.title) },
label = { Text(text = item.title) },
selectedContentColor = Color.White,
unselectedContentColor = Color.White.copy(0.4f),
alwaysShowLabel = true,
selected = currentRoute == item.route,
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
navController.graph.startDestinationRoute?.let { route ->
popUpTo(route) {
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
}
}
)
}
}
}

Thats It. You are ready with BottomNaviagtionBar Integration with Compose and Jetpack Navigation.

Find Code on Github — https://github.com/radaurgaurav/BottomNavigationInCompose

--

--

--

Android App Developer, Yoga Practitioner, Running Enthusiast

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Handling Multiple Permission using Jetpack Compose

How to create a Bottom Navigation Bar in Kotlin — In-Depth Guide

Upload an Image or File To Your Server Using Volley in Kotlin

Exploring and Building Android App Widgets With Glance APIs

Implement HMS Map Kit with Flutter

Introduction to Android’s CameraX With Java

Hello UI testing in Android

WHAT IS MARGIN TRADING ⁉️ Want to Know more about MARGIN TRADING?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Gaurav

Gaurav

Android App Developer, Yoga Practitioner, Running Enthusiast

More from Medium

Handle repetition in records for pagination in JSON-RPC API call

File System Of Android

Kotlin Multi Platform For Mobile

Updating React-map marker position in real-time using socket.io and Kafka.