Jetpack Compose is Google’s modern UI toolkit for building native Android apps. It provides a declarative way to design user interfaces, making development faster and more intuitive. One common UI pattern in mobile apps is bottom navigation, which allows users to quickly switch between top-level views or features. Integrating bottom navigation in Jetpack Compose involves using the BottomNavigation
and BottomNavigationItem
composables.
What is Bottom Navigation?
Bottom navigation is a UI component that appears at the bottom of a mobile app screen. It typically consists of several icons or text labels that represent different sections or features of the app. When a user taps on an item in the bottom navigation, the app navigates to the corresponding screen or view.
Why Use Bottom Navigation?
- Improved User Experience: Provides quick access to essential features.
- Intuitive Navigation: Simplifies app navigation with clear visual cues.
- Enhanced Accessibility: Easier to reach than top navigation, especially on larger screens.
How to Implement Bottom Navigation in Jetpack Compose
Implementing bottom navigation in Jetpack Compose involves the following steps:
Step 1: Add Dependencies
Ensure you have the necessary dependencies in your build.gradle
file. You’ll need Compose UI and Navigation dependencies:
dependencies {
implementation("androidx.compose.ui:ui:1.6.4")
implementation("androidx.compose.material:material:1.6.4")
implementation("androidx.navigation:navigation-compose:2.7.7")
implementation("androidx.compose.ui:ui-tooling-preview:1.6.4")
debugImplementation("androidx.compose.ui:ui-tooling:1.6.4")
}
Step 2: Define Navigation Items
Create data classes to represent each item in the bottom navigation:
import androidx.compose.ui.graphics.vector.ImageVector
data class BottomNavItem(
val name: String,
val route: String,
val icon: ImageVector,
val badgeCount: Int = 0
)
Step 3: Create the BottomNavigation
Composable
Implement the BottomNavigation
composable with BottomNavigationItem
for each navigation item:
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.currentBackStackEntryAsState
@Composable
fun BottomNavigationBar(navController: NavController, items: List<BottomNavItem>) {
BottomNavigation(
backgroundColor = Color.White,
contentColor = Color.Black
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
items.forEach { item ->
BottomNavigationItem(
icon = { Icon(imageVector = item.icon, contentDescription = item.name) },
label = {
Text(
text = item.name,
fontSize = 9.sp
)
},
selectedContentColor = Color.Black,
unselectedContentColor = Color.Gray,
alwaysShowLabel = true,
selected = currentRoute == item.route,
onClick = {
navController.navigate(item.route) {
navController.graph?.startDestinationRoute?.let { route ->
popUpTo(route) {
saveState = true
}
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
Step 4: Define Navigation Graph
Set up the navigation graph using NavController
and NavHost
:
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Scaffold
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Email
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
@Composable
fun MainScreen() {
val navController = rememberNavController()
val items = listOf(
BottomNavItem(
name = "Home",
route = "home",
icon = Icons.Default.Home
),
BottomNavItem(
name = "Chat",
route = "chat",
icon = Icons.Default.Email,
badgeCount = 23
),
BottomNavItem(
name = "Settings",
route = "settings",
icon = Icons.Default.Settings
)
)
Scaffold(
bottomBar = {
BottomNavigationBar(
navController = navController,
items = items
)
}
) {
Column(
modifier = Modifier
.fillMaxSize()
) {
// Add padding here or handle it in individual screen composables
NavHost(navController = navController, startDestination = "home") {
composable("home") {
HomeScreen()
}
composable("chat") {
ChatScreen()
}
composable("settings") {
SettingsScreen()
}
}
}
}
}
@Composable
fun HomeScreen() {
Text(text = "Home Screen")
}
@Composable
fun ChatScreen() {
Text(text = "Chat Screen")
}
@Composable
fun SettingsScreen() {
Text(text = "Settings Screen")
}
Step 5: Add Screens
Create composable functions for each screen or feature in the bottom navigation:
@Composable
fun HomeScreen() {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Home Screen", fontSize = 24.sp)
}
}
@Composable
fun ChatScreen() {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Chat Screen", fontSize = 24.sp)
}
}
@Composable
fun SettingsScreen() {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Settings Screen", fontSize = 24.sp)
}
}
Step 6: Preview and Test
Use the @Preview
annotation to preview the bottom navigation in the IDE and test the navigation on an emulator or physical device.
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
MainScreen()
}
Conclusion
Integrating bottom navigation in Jetpack Compose provides an intuitive and efficient way to navigate between different sections of your Android app. By defining navigation items, implementing the BottomNavigation
composable, setting up the navigation graph, and adding screen composables, you can create a seamless and user-friendly navigation experience. Jetpack Compose’s declarative approach simplifies the process and allows for easy customization to match your app’s design and functionality. Proper use of bottom navigation can significantly enhance the overall user experience and app engagement.