Tabbed Navigation in Jetpack Compose
In this exercise, you will create a Bottom Navigation for the Little Lemon app to navigate to the primary destinations such as Menu, Home and Location.
🟢 ANDROID WITH MACHINE LEARNING! (COURSE)
🟢 KOTLIN INTERVIEW BOOTCAMP! (COURSE)
Step 1: Create the destination file and the interface.
First, you should create the Destinations file under the package name. Inside the file, define an interface Destinations which will have:
1. Route
2. Icon
3. Title
Hint: Previously, we were using the icons from the material library. But now they will be from the drawable resources, so they should be of int type.
interface Destinations {
val route: String
val icon: Int
val title: String
}
object Menu : Destinations {
override val route = "Menu"
override val icon = R.drawable.ic_menu
override val title = "Menu"
}
object Home : Destinations {
override val route = "Home"
override val icon = R.drawable.ic_home
override val title = "Home"
}
object Location : Destinations {
override val route = "Location"
override val icon = R.drawable.ic_location
override val title = "Location"
}
Step 2: Create the objects by implementing the interface.
Create the Menu, Home, and Location objects and assign the associated values for the route, icon, and title overridden variable.
Hint: To assign the value of the location, you will pass its id to the icon object, for example
R.drawable.ic_home
Step 3: Create the Bottom Navigation composable:
In the MainActivity.kt file, create a MyBottomNavigation composable with a parameter of navController. Inside the composable, create a list of Destinations and add all three destinations created in Step 2.
Create a variable selectedIndex by rememberSaveable having the mutableStateOf with 1 value for the Home item to be selected initially.
Call the BottomNavigation{} composable. Inside the trailing lambda of BottomNavigation{}, iterate the list for creating the BottomNavigationItem for each destination. Because index is required you can call the forEachIndexed with parameter index and destination.
Inside the ForEach block, add the BottomNavigationItem and set the icon parameter to curly braces containing a Text object with text equal to the destination title.
Similarly, set the icon parameter to the Icon object whose painter parameter will be set to painter resource with the id equal to the destination id.
Set the selected index to the comparison of index with selectedIndex.value.
Set the onClick parameter to update the selected index to the index.
And use the nav controller to navigate to the selected index in the destination list’s route.
Remember to avoid adding the screen multiple times to the back stack the launchSingleTop is set to true. And to go to Home from each destination it is required to call the popUpTo function with home route.
@Composable
fun MyBottomNavigation(navController: NavController) {
val destinationList = listOf(
Menu,
Home,
Location
)
val selectedIndex = rememberSaveable {
mutableStateOf(0)
}
BottomNavigation {
destinationList.forEachIndexed { index, destination ->
BottomNavigationItem(
label = { Text(text = destination.title) },
icon = {
Icon(
painter = painterResource(id = destination.icon),
contentDescription = destination.title
)
},
selected = index == selectedIndex.value,
onClick = {
selectedIndex.value = index
navController.navigate(destinationList[index].route) {
popUpTo(Home.route)
launchSingleTop = true
}
})
}
}
}
tep 4: Finalize the top-level composable
Now create a composable MyApp.
Inside the composable, create a nav controller for passing to the navigation through rememberNavController().
Now, add a scaffold and call the MyBottomNavigation composable by passing the navController as a parameter inside the trailing lambda of the bottomBar to set the navigation.
Add a box inside the curly braces of the Scaffold and set the padding to the parameter provided by the Scaffold.
Inside the Box, call the NavHost composable and set the nav controller parameter to the nav controller created above.
Now call the composable function for the Menu route, and inside the trailing lambda of the function, call the MenuScreen() composable.
Repeat the composable call with the call to screens in the same way for HomeScreen and LocationScreen
Finally, call the MyApp inside the setContent of the MainActivity and run the app.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApp()
}
}
}
@Composable
fun MyApp() {
val navController = rememberNavController()
Scaffold(bottomBar = { MyBottomNavigation(navController = navController) }) {
Box(Modifier.padding(it)) {
NavHost(navController = navController, startDestination = Home.route) {
composable(Menu.route) {
MenuScreen()
}
composable(Home.route) {
HomeScreen()
}
composable(Location.route) {
LocationScreen()
}
}
}
}
}
Conclusion
By completing the exercise, you have demonstrated your ability to configure and utilize the BottomNavigation.
💯