How to Add Bottom Navigation in Jetpack Compose?
Step-by-step guides to add bottom navigation in Jetpack Compose for beginners
This is part of the Jetpack Compose navigation series:
Part 3 - How to Add Bottom Navigation in Jetpack Compose?
This article shows the steps that you need to do to add the bottom navigation from this simple navigation in Jetpack Compose example in part 1.
1. Add Icon Vector Asset
In this example, you're adding the ic_home.xml
and ic_search.xml
vector assets for the screen navigation tab.
This highlights the steps :
New -> ** Vector Asset**
Click on the Clip Art to select the Icon asset
Rename it
You may get the following compilation error after adding those icons. AAPT: error: resource attr/colorControlNormal not found.
It is because of the dependency on the androidx.appcompat:appcompat
library, which is not required by Jetpack Compose app.
To fix the error, add this library into your app\build.gradle
file:
dependencies {
// required by "?attr/colorControlNormal" ic_home.xml
implementation 'androidx.appcompat:appcompat:1.4.1'
}
[Updated - Sept 27, 2022]: It looks like this step is unnecessary because we can just reference
ImageVector
directly from the code usingIcons.Default.Home
. So this dependencyimplementation 'androidx.appcompat:appcompat:1.4.1'
can be removed as well.
2. Add BottomNavigation() Composable
androidx.compose.material.BottomNavigation()
composable function is used to implement the bottom bar navigation.
@Composable
fun BottomBarNavigation(navController: NavController) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
if (currentRoute == null || currentRoute == NavRoute.Login.path) {
return
}
BottomNavigation {
// implement each navigation tab with BottomNavigationItem() here
}
}
navController.currentBackStackEntryAsState()
is used so that it can retrigger the composable function to run when the navigation route is changed.
3. Add BottomNavigationItem() Composable
In the BottomNavigation(), you add the RowScope.BottomNavigationItem()
for each row navigation tab.
BottomNavigation {
val homeSelected = currentRoute == NavRoute.Home.path
BottomNavigationItem(
icon = {
Icon(
painter = painterResource(R.drawable.ic_home),
contentDescription = NavRoute.Home.path
)
},
selected = homeSelected,
onClick = {
if(!homeSelected) {
navController.navigate(NavRoute.Home.path) {
popUpTo(NavRoute.Home.path) { inclusive = true }
}
}
},
label = {Text(NavRoute.Home.path)}
)
}
icon
,selected
andonClick
are mandatory parameters, the rest are optional.
[Updated - Sept 27, 2022]: Since importing icon asset manually is no longer needed (see above section), you replace
Icon(
painter = painterResource(R.drawable.ic_home),
contentDescription = NavRoute.Home.path
)
with
Icon(
imageVector = Icons.Default.Home,
contentDescription = NavRoute.Home.path
)
The commit changes are here.
4. Implement Scaffold bottomBar
To add BottomBarNavigation()
, you call it from the Scaffold -> bottomBar
parameter as the following:
val navController = rememberNavController()
Scaffold(
bottomBar = { BottomBarNavigation(navController = navController) }
) {
NavGraph(navController)
}
[Updated - Sept 28, 2022]: While working on this Simple RSS Feed reader app, I noticed that the content is covered by this bottom bar navigation. To fix that, I used
PaddingValues.calculateBottomPadding()
from theScaffold()
to add the bottom padding of the content.
- Use
paddingValues.calculateBottomPadding()
to calculate the required bottom bar padding
val navController = rememberNavController()
Scaffold(
bottomBar = { BottomBarNav(navController = navController) }
) { paddingValues ->
NavGraph(
modifier = Modifier.padding(
bottom = paddingValues.calculateBottomPadding()),
navController = navController
)
}
- Add
Modifier
parameter intoNavGraph()
andNavHost()
@Composable
fun NavGraph(
modifier: Modifier = Modifier,
navController: NavHostController) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = NavRoute.Login.path
) {
/*...*/
}
}
Source Code
GitHub Repository: Demo_SimpleNavigationCompose (bottom_nav branch)