How to Add Bottom Navigation in Jetpack Compose?
Tags: android, beginners, kotlin, jetpackcompose
Published: 2022-06-24 21:35:37

**Step-by-step guides to add bottom navigation in Jetpack Compose for beginners**

This is part of the Jetpack Compose navigation series:

*   [Part 1 - Simple Jetpack Compose Navigation Example](https://vtsen.hashnode.dev/simple-jetpack-compose-navigation-example)
    
*   [Part 2 - Compose Destinations - Navigation Library](https://vtsen.hashnode.dev/compose-destinations-navigation-library)
    
*   **Part 3 - How to Add Bottom Navigation in Jetpack Compose?**
    
*   [Part 4 - How to Add Navigation Drawer in Jetpack Compose?](https://vtsen.hashnode.dev/how-to-add-navigation-drawer-in-jetpack-compose)

* [Part 5 - How to Add Deep Links in Jetpack Compose?](https://vtsen.hashnode.dev/how-to-add-deep-links-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.

![How_to_Add_Bottom_Navigation _in_Jetpack_Compose_00.gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/usza0yi097ph59qzrwhg.gif)

## 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

![How_to_Add_Bottom_Navigation _in_Jetpack_Compose_01.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1644807356575/P1dReWLGg.gif)

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 using `Icons.Default.Home`. So this dependency `implementation '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. 

```kotlin
@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.

```kotlin
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` and `onClick` are mandatory parameters, the rest are optional.

**[Updated - Sept 27, 2022]:** Since importing icon asset manually (see above section) is no longer needed, you replace

```kotlin
Icon(
    painter = painterResource(R.drawable.ic_home),
    contentDescription = NavRoute.Home.path
)
```

with

```kotlin
Icon(
    imageVector = Icons.Default.Home,
    contentDescription = NavRoute.Home.path
)
```

The commit changes are [here](https://github.com/vinchamp77/Demo_SimpleNavigationCompose/commit/9df46f7f5df7709f6be6b781368ed57f01b2657c).

## 4. Implement Scaffold bottomBar 

To add `BottomBarNavigation()`, you call it from the `Scaffold -> bottomBar` parameter as the following:

```kotlin
val navController = rememberNavController()

Scaffold(
	bottomBar = { BottomBarNavigation(navController = navController) }
) {
	NavGraph(navController)
}
```

> **[Updated - Sept 28, 2022]:** While working on this [Simple RSS Feed reader](https://vtsen.hashnode.dev/simple-rss-feed-reader-jetpack-compose) app, I noticed that the content is covered by this bottom bar navigation. To fix that, I used 
`PaddingValues.calculateBottomPadding()` from the `Scaffold()` to add the bottom padding of the content.

- Use `paddingValues.calculateBottomPadding()` to calculate the required bottom bar padding

```kotlin
val navController = rememberNavController()

Scaffold(
    bottomBar = { BottomBarNav(navController = navController) }
) { paddingValues ->
    NavGraph(
        modifier = Modifier.padding(
            bottom = paddingValues.calculateBottomPadding()),
        navController = navController
    )
}
```

- Add `Modifier` parameter into `NavGraph()` and `NavHost()`

```kotlin
@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)](https://github.com/vinchamp77/Demo_SimpleNavigationCompose/tree/bottom_nav)

---

*Originally published at [https://vtsen.hashnode.dev](https://vtsen.hashnode.dev/how-to-add-bottom-navigation-in-jetpack-compose)*.