Mastering BottomAppBar Navigation in Jetpack Compose

The BottomAppBar is a key component of Material Design that provides a dedicated space for actions and navigation at the bottom of the screen. In Jetpack Compose, the BottomAppBar offers a clean and efficient way to display essential UI elements and navigation options. This blog post explores how to effectively use the BottomAppBar in Jetpack Compose to create a modern and user-friendly Android application.

What is BottomAppBar in Jetpack Compose?

BottomAppBar is a composable function provided by the Material Design library for Jetpack Compose. It displays a bar at the bottom of the screen that typically contains navigation icons and action buttons. It is designed to align with Material Design principles, enhancing the app’s usability and aesthetic appeal.

Why Use BottomAppBar?

  • Improved Navigation: Offers a consistent and accessible way to navigate between different sections of the app.
  • Key Actions at Hand: Allows users to quickly access important actions and functionalities.
  • Material Design Compliance: Adheres to Material Design guidelines, providing a modern and cohesive UI.

How to Implement BottomAppBar in Jetpack Compose

To implement a BottomAppBar in Jetpack Compose, follow these steps:

Step 1: Add Dependencies

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

dependencies {
    implementation("androidx.compose.material3:material3:1.1.1")
    implementation("androidx.compose.ui:ui:1.5.4") // Ensure latest version for stability
    implementation("androidx.compose.ui:ui-tooling-preview:1.5.4")
    debugImplementation("androidx.compose.ui:ui-tooling:1.5.4") // Keep ui-tooling dependency consistent with ui dependency

}

Step 2: Basic BottomAppBar Implementation

Implement the BottomAppBar composable with navigation and action items.


import androidx.compose.material3.BottomAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material3.IconButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview

@Composable
fun SimpleBottomAppBar() {
    BottomAppBar(
        content = {
            IconButton(onClick = { /* doSomething() */ }) {
                Icon(Icons.Filled.Menu, contentDescription = "Menu")
            }
        }
    )
}

@Preview(showBackground = true)
@Composable
fun SimpleBottomAppBarPreview() {
    SimpleBottomAppBar()
}

In this example, a basic BottomAppBar is created with a menu icon that triggers an action when pressed.

Step 3: Adding More Navigation Icons

You can add multiple icons to create a fully functional navigation bar.


import androidx.compose.material3.BottomAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.IconButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha

@Composable
fun EnhancedBottomAppBar() {
    BottomAppBar {
        IconButton(onClick = { /* Handle navigation to Home */ }) {
            Icon(Icons.Filled.Home, contentDescription = "Home")
        }
        IconButton(onClick = { /* Handle navigation to Search */ }) {
            Icon(Icons.Filled.Search, contentDescription = "Search")
        }
        IconButton(onClick = { /* Handle navigation to Account */ }) {
            Icon(Icons.Filled.AccountCircle, contentDescription = "Account")
        }
        IconButton(onClick = { /* Handle more options */ }) {
            Icon(Icons.Filled.MoreVert, contentDescription = "More")
        }
    }
}

@Preview(showBackground = true)
@Composable
fun EnhancedBottomAppBarPreview() {
    EnhancedBottomAppBar()
}

Here, several icons representing different navigation destinations are included within the BottomAppBar.

Step 4: Incorporating the FloatingActionButton

Often, BottomAppBar is used with a FloatingActionButton (FAB) to perform a primary action.


import androidx.compose.material3.BottomAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.IconButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.graphics.Color

@Composable
fun BottomAppBarWithFAB() {
    BottomAppBar(
        actions = {
            IconButton(onClick = { /* Handle navigation to Home */ }) {
                Icon(Icons.Filled.Home, contentDescription = "Home")
            }
            IconButton(onClick = { /* Handle navigation to Search */ }) {
                Icon(Icons.Filled.Search, contentDescription = "Search")
            }
            IconButton(onClick = { /* Handle navigation to Account */ }) {
                Icon(Icons.Filled.AccountCircle, contentDescription = "Account")
            }
        },
        floatingActionButton = {
            FloatingActionButton(onClick = { /* Handle FAB click */ },
				containerColor = Color.Green) {
                Icon(Icons.Filled.Add, "Add")
            }
        }
    )
}

@Preview(showBackground = true)
@Composable
fun BottomAppBarWithFABPreview() {
    BottomAppBarWithFAB()
}

In this extended example:

  • Actions such as “Home,” “Search,” and “Account” navigation are incorporated into the BottomAppBar.
  • A FloatingActionButton is added with an “Add” icon, set to perform a specific primary action.
  • The FAB’s background color is customized to green, providing a visual distinction.

Step 5: Adding Cutout for the FAB

You may want the BottomAppBar to have a cutout shape behind the FloatingActionButton (FAB), creating a visually engaging interface.

This is often managed at the Scaffold level (as direct cutout customization is not a standard BottomAppBar property but a Scaffold design feature):


import androidx.compose.material3.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Alignment
import androidx.compose.material3.Scaffold

@Composable
fun BottomAppBarWithFABAndCutout() {
    Scaffold(
        bottomBar = {
            BottomAppBar(
                actions = {
                    IconButton(onClick = { /* Handle navigation to Home */ }) {
                        Icon(Icons.Filled.Home, contentDescription = "Home")
                    }
                    IconButton(onClick = { /* Handle navigation to Search */ }) {
                        Icon(Icons.Filled.Search, contentDescription = "Search")
                    }
                    IconButton(onClick = { /* Handle navigation to Account */ }) {
                        Icon(Icons.Filled.AccountCircle, contentDescription = "Account")
                    }
                },
                floatingActionButton = {
                    FloatingActionButton(
                        onClick = { /* Handle FAB click */ },
                        containerColor = MaterialTheme.colorScheme.secondaryContainer,
                        elevation = FloatingActionButtonDefaults.elevation(defaultElevation = 6.dp)
                    ) {
                        Icon(Icons.Filled.Add, "Add")
                    }
                },
                floatingActionButtonPosition = FabPosition.Center
            )
        },
        content = { padding ->
            // Scaffold content will be placed here, make sure to use `padding`
            // to avoid content overlapping the bottom bar.  This `padding` value is
            // provided by the Scaffold so you don't need to calculate it.
            Box(modifier = androidx.compose.ui.Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                Text("Content of the Screen with BottomAppBar", modifier = androidx.compose.ui.Modifier.padding(padding))
            }

        }
    )
}

@Preview(showBackground = true)
@Composable
fun BottomAppBarWithFABAndCutoutPreview() {
    BottomAppBarWithFABAndCutout()
}

Important Updates/Improvements:

  • floatingActionButtonPosition = FabPosition.Center positions the FAB centered on the bottom app bar.
  • Ensure you wrap your screen content inside the Scaffold’s content parameter with a Box that applies the provided padding. This keeps content from overlapping the BottomAppBar, resulting in clean and unobstructed UI rendering.
  • Dependency: make sure androidx.compose.material3:material3 is above 1.1.0 version to be compatible with the code, if not errors in code, ensure androidx.compose.ui:ui dependencies are in the last versions 1.5.4

Conclusion

The BottomAppBar in Jetpack Compose is an invaluable tool for creating consistent and accessible navigation and actions at the bottom of your app screen. Properly implemented, it aligns with Material Design principles, improving usability and providing an intuitive user experience. Whether you’re adding simple navigation icons or integrating a FloatingActionButton with a cutout, BottomAppBar offers the flexibility needed for modern Android UI design.