Navigation UI Components
Introduction to Navigation UI
Navigation UI components are the visual elements that help users move around your app. Think of them like signs and doors in a building - they show users where they can go and how to get there. In this lesson, we'll learn about two common navigation UI components:
| Component | Where It Goes | What It's For | When to Use |
|---|---|---|---|
| Top App Bar | Top of the screen | Show app title and important actions | App-wide actions, context, or navigation. Note the or navigation part. |
| Bottom Navigation Bar | Bottom of the screen | Switch between main app sections | 3-5 top-level destinations |
Top App Bar
The Top App Bar (also called Action Bar) is like a header that stays at the top of your screen. It's great for showing the current screen title and navigation actions.
// NavigationRoutes.kt
object NavigationRoutes {
const val HOME = "home"
const val PROFILE = "profile"
const val SETTINGS = "settings"
}
// TopNavigation.kt
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TopNavigationBar(navController: NavController) {
val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
TopAppBar(
title = { Text("Top Navigation Bar") },
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.onPrimaryContainer
),
actions = {
IconButton(onClick = {
navController.navigate(NavigationRoutes.HOME) { launchSingleTop = true }
}) {
Icon(
imageVector = Icons.Filled.Home,
contentDescription = "Home",
tint = if (currentRoute == NavigationRoutes.HOME) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onPrimaryContainer
)
}
IconButton(onClick = {
navController.navigate(NavigationRoutes.PROFILE) { launchSingleTop = true }
}) {
Icon(
imageVector = Icons.Filled.Person,
contentDescription = "Profile",
tint = if (currentRoute == NavigationRoutes.PROFILE) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onPrimaryContainer
)
}
IconButton(onClick = {
navController.navigate(NavigationRoutes.SETTINGS) { launchSingleTop = true }
}) {
Icon(
imageVector = Icons.Filled.Settings,
contentDescription = "Settings",
tint = if (currentRoute == NavigationRoutes.SETTINGS) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onPrimaryContainer
)
}
}
)
}
// MainScreen.kt
@Composable
fun MainScreen() {
val navController = rememberNavController()
Scaffold(
topBar = { TopNavigationBar(navController) }
) { paddingValues ->
NavHost(
navController = navController,
startDestination = NavigationRoutes.HOME,
modifier = Modifier.padding(paddingValues)
) {
composable(NavigationRoutes.HOME) { HomeScreen() }
composable(NavigationRoutes.PROFILE) { ProfileScreen() }
composable(NavigationRoutes.SETTINGS) { SettingsScreen() }
}
}
}
How the Top App Bar works:
- The top app bar is like a header at the top of your screen that shows your app's name and navigation buttons
- It's different from the bottom navigation bar because it's meant for app-level actions and showing where you are in the app
- In the code, we use
topBarin theScaffoldto put it at the top of the screen - It can show a back button when you're not on the home screen
- While it can have navigation buttons, its main job is to show your app's title and important actions
How this example renders
Above is just a snippet of the code to view the full code, you need to go to my GitHub page and look at the chapter9 topNavBar.kt file.
Bottom Navigation Bar
The bottom navigation bar is perfect for switching between the main sections of your app. It's like having a row of buttons at the bottom of the screen that take you to different places.
/ NavigationRoutes.kt
object NavigationRoutes {
const val HOME = "home"
const val PROFILE = "profile"
const val SETTINGS = "settings"
}
// BottomNavigation.kt
@Composable
fun BottomNavigationBar(navController: NavController) {
val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
NavigationBar {
NavigationBarItem(
icon = { Icon(Icons.Filled.Home, contentDescription = "Home") },
label = { Text("Home") },
selected = currentRoute == NavigationRoutes.HOME,
onClick = {
navController.navigate(NavigationRoutes.HOME) {
launchSingleTop = true
}
}
)
NavigationBarItem(
icon = { Icon(Icons.Filled.Person, contentDescription = "Profile") },
label = { Text("Profile") },
selected = currentRoute == NavigationRoutes.PROFILE,
onClick = {
navController.navigate(NavigationRoutes.PROFILE) {
launchSingleTop = true
}
}
)
NavigationBarItem(
icon = { Icon(Icons.Filled.Settings, contentDescription = "Settings") },
label = { Text("Settings") },
selected = currentRoute == NavigationRoutes.SETTINGS,
onClick = {
navController.navigate(NavigationRoutes.SETTINGS) {
launchSingleTop = true
}
}
)
}
}
// MainScreen.kt
@Composable
fun MainScreen() {
val navController = rememberNavController()
Scaffold(
bottomBar = { BottomNavigationBar(navController) }
) { paddingValues ->
NavHost(
navController = navController,
startDestination = NavigationRoutes.HOME,
modifier = Modifier.padding(paddingValues)
) {
composable(NavigationRoutes.HOME) { HomeScreen() }
composable(NavigationRoutes.PROFILE) { ProfileScreen() }
composable(NavigationRoutes.SETTINGS) { SettingsScreen() }
}
}
}
How Bottom Navigation Works:
- Think of the bottom navigation bar like a row of buttons at the bottom of your screen that let you jump to different parts of your app
- Each button (called a
NavigationBarItem) has an icon and a label to show what it does - The current section you're on will be highlighted automatically
- It's perfect for apps with 3-5 main sections (like Home, Profile, Settings)
- In the code, we use
bottomBarin theScaffoldto put it at the bottom of the screen
How this example renders
Above is just a snippet of the code to view the full code, you need to go to my GitHub page and look at the chapter9 bottomNavBar.kt file.
Bottom Navigation vs Top App Bar: What's the Difference?
- Where they go:
- Bottom Navigation Bar goes at the bottom of your screen
- Top App Bar goes at the top of your screen
- What they're for:
- Bottom Navigation Bar is for switching between the main parts of your app (like Home, Profile, Settings)
- Top App Bar is for showing your app's name and important actions at the top
- When to use each:
- Use Bottom Navigation when you want users to easily switch between main sections of your app
- Use Top App Bar when you want to show the app name and important actions at the top of the screen
Where Do the Icons Come From?
In our examples, we use icons from the Material Icons library. These are built into Android and easy to use. Here's how we get them:
// Import the icons we want to use
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.filled.Settings
// Then use them in our code
Icon(Icons.Filled.Home, contentDescription = "Home")
Icon(Icons.Filled.Person, contentDescription = "Profile")
Icon(Icons.Filled.Settings, contentDescription = "Settings")
Some things to know about Material Icons:
- They're free to use and come with Android
- There are many icons to choose from (like Home, Settings, Person, etc.)
- You can find all available icons in Android Studio by typing
Icons.Filled.and looking at the suggestions - Always include a
contentDescriptionfor accessibility
Tips for Success
- Choose the right navigation component for your app's needs
- Keep navigation consistent throughout your app
- Use clear icons and labels
- Test navigation on different screen sizes
Common Mistakes to Avoid
- Using too many navigation components at once
- Unclear icons or labels
- Inconsistent navigation patterns
- Not handling back navigation properly