Originally published at https://wajahatkarim.com.
After introduction of Fragments in Android Honeycomb, it became obvious to use more Fragments in preference to Activities to make apps lighter and faster. Google also started recommending single activity architecture. But implementing it has been a real pain-point for developers. The major cause of this is the Fragments and its transactions overhead. Its very hard to learn, debug, and deal with whole mess of
IllegalStateException of Fragments.
Finally Google heard its developers and introduced Android Jetpack. Its a suite of libraries and tools to help developers in making high-quality scalable apps easier and faster. It provides solutions to lots of problems such as architecture guidelines, background tasks scheduling, and of course the Navigation.
👌 Jetpack Navigation
Jetpack Navigation, or Android navigation component, is a part of Android Jetpack components and provides developers tools to create single activity apps with a visual drag-drop representation and easy interface. It manages the whole Fragment transactions overhead itself and gives a simple API to deal with the navigation in intuitive and readable way.
Using Jetpack Navigation, you can separate navigation flow from the other parts of code like business logic, database operations etc. This way navigation flow can be easily modified without having to make many changes in the code. It also eliminates the need to write boilerplate code to link fragments or activities in applications.
In this tutorial, we will discuss on how we can create Bottom Navigation using the awesome Jetpack Navigation component and see how easy and fun it is to work with it.
🎯 The Demo App & Code
This demo covers the following 5 use-cases of the Bottom Navigation.
- 🚀 Simple Bottom Navigation with Jetpack Navigation — Part 1
- 🎨 Adjusting AppBar/Toolbar for Top Level Destinations — Part 1
- ☑️ Adding Menu Options in Some Screens — Part 2
- 🗒 Creating Detail Screens for Some Screens — Part 2
- 🛑 Quitting app on Double Back-Press Tap — Part 2
This article covers the first two use-cases and others are covered in the second part of the article.
The code of this app is available on my Github profile at following repository.
💻 Let’s Get Started
To make things easier, I have created a separate branch of the app as the starting point of the application. This branch contains basic structure of app with Bottom Navigation, colors resources, and empty Fragment classes with their layout files already. Go ahead, and clone the start-here branch from this link: https://github.com/wajahatkarim3/BottomNavArchDemo/tree/start-here
A demo project to create Bottom Navigation with Jetpack Navigation in Android and discusses the details in the…
Here’s a quick explanation of the code:
- MainActivity.kt: The main launcher
Activityclass. This will be the only single Activity of the application. This contains the
FrameLayoutas a placeholder for other screens of the app.
- The empty fragments, HomeFragment, SearchFragment, NotificationsFragment, NotificationDetailsFragment, and ProfileFragment: All these classes are just simple empty Fragment showing a simple centered text message with the title of the fragment.
- menu/bottom_navigation_menu.xml: This file contains the menu items of the bottom navigation: Home, Search, Notification, and Profile with their menu item IDs, titles, and icons.
🔧 Including Jetpack Navigation in Your Apps
Let’s start by including the Jetpack Navigation library in your apps by adding these lines in app’s
We will use the Material Components
BottomNavigationView for our bottom navigation. So, you need to add that too in case you haven’t already. You can use other bottom navigation views such as of the Android X or some third party library etc. It will work in same way as this tutorial do. Check the Material Components documentation for more details on this.
🚀 Simple Bottom Navigation with Jetpack Navigation
We start by creating a simple bottom navigation flow first. For that, you need to do first add
NavHostFragment in your single activity layout file. Add this in the
activity_main.xml file inside the
You will see an error saying “Cannot resolve symbol
NavHostFragment as described by the
android:name attribute in the above code behaves as place holder for all the other fragments (also known as destinations ) of the app.
With Jetpack Navigation, all the destinations are defined in the XML, which includes the definition for linking of destinations. And you have to trigger these screens in responses to events on a UI widget of any screen from the code. These triggers are called as navigation actions.
The XML which contains navigation info is created in
navigation resource folder. To define destinations, you can directly add corresponding elements to it in XML code or it can be created using the navigation editor which can be accessed by opening this navigation XML file.
res/naviation/bottom_nav_graph.xml file. After opening the file, you will see something like this:
We don’t have any screens or destinations added yet. The code of this file will be this:
Now, add your first destination “Home” by clicking on the Plus (+) button as shown in the image below and select the
fragment_home from the list.
Repeat this process for the
Profile fragments as well, and these all fragments will look like screens like the image below.
You can drag these screens around to arrange on your convenience. The Home icon before the Home screen’s ID
homeFragment2 indicates that this the starting destination of the whole app. This means that when you run the app, you will automatically see “Home” screen first.
Here’s the code in this file:
You might be wondering why the IDs of these destinations have “2” term. For example,
homeFragment2 instead of
homeFragment. This is because the original IDs are already declared in the
menu/bottom_navigation_menu.xml file. As discussed earlier, this file provides the menu options to bottom navigation view, their icons, and titles etc.
If you want to connect
BottomNavigationView and navigation destinations, then you need to declare same IDs in both menu and navigation files. So, just remove the “2” suffix from all IDs of navigation file and the final IDs of all destinations will be
profileFragment. You can change these IDs either directly from the XML code or through the Attributes panel on the right side in navigation design view.
Its time for add some code in our activity class. Open
MainActivity.kt file, and create a method
setupViews() in it. Call this in
onCreate() of the activity. Add these lines in the
At the lines 3-4, we are calling the method
findNavController and passing the ID of our
NavHost fragment from the
activity_main.xml layout file. This will give us the Navigation Controller. With this controller, we can trigger the screens and control the navigation from the code.
At lines 6-7, we are connecting the navigation controller object (
navController) with our
bottomNavigationView . This is it.
Remember, you have to keep the same IDs of the destinations in the navigation graph file and menu items in the menu of BottomNavigationView file. And now run the application and you will see all sections of bottom navigation will work and show the respective fragments. Here’s the GIF of the running app.
As show in the demo GIF above, all sections are showing their respective screens. And pressing back moves back to Home screen, and then pressing back again exits the application.
🎨 Adjusting AppBar/Toolbar for Top Level Destinations
But there’s one issue. The Toolbar/Appbar label is not changing at all. You can do it very easily by calling the method
setupActionBarWithNavController() in the
setupViews() method like the code below.
Now, run the application. You will see the label of each screen such as
fragment_search etc. in the
ActionBar. You can change these labels in your Navigation file either through XML code with
android:label or directly from the Attributes panel as in the image below.
Set these to Home, Search, Notifications, and Profile for all your destinations. And your app will look the GIF below.
You can see that your
ActionBar is applying the right label. But there’s a back arrow in the other 3 sections except Home. This is behaving like Home is the parent section and others are the children sections.
You can easily fix this by using the
AppBarConfiguration class. You need to declare the top-level destinations in its constructor and pass this in
setupActionBarWithNavController() method. Here’s the modified
You can see that we have passed main 4 sections’ IDs in the
topLevelDestinationIds paremter. Now, run the app and you won’t see any back arrow on any main section. Here’s the final demo GIF.
🎯 Conclusion & What’s Next
We learned on how to create a simple top-level sections navigation of BottomNavigationView with Jetpack Navigation component in Android. We also saw how we can customize the Toolbar behavior with Jetpack Navigation. The code of this basic demo is available on the “basic-bottom-nav-toolbar” branch of the BottomNavArchDemo repository here.
In the next article, we will discuss about the following use-cases in Bottom Navigation with Jetpack Navigation component.
- ☑️ Adding Menu Options in Some Screens
- 🗒 Creating Detail Screens for Some Screens
- 🛑 Quitting app on Double Back-Press Tap
You can read it on the following link:
If you liked this article, you can read my new articles below:
🕐 Revisited — 📚 A Guide on Splash Screen in Android in 2020
👀 A fresh look on the splash screen in Android in Kotlin and Coroutines
Originally published at https://wajahatkarim.com.