Single Activity App Using Android Navigation Architecture Component
Do you have a complex navigation flow which you want to simplify in your app or maybe you just don’t want to deal with the back stack anymore but you still want your app to be predictable and consistent?
Quoting the documentation, Navigation Architecture Component helps you implement common, but complex navigation requirements in your app, enabling you to more easily provide consistent and predictable experiences for your users.
Navigation handles navigating between your app’s destinations — that is, anywhere in your app to which users can navigate.
Setting Up Navigation Architecture Component
Navigation Component requires you to have Android Studio 3.2 or higher. I am currently using 3.3 however I don’t recommend the transition from 3.2 to 3.3 yet as there are still random warnings and bugs. If you are using 3.2 then you need to make sure that you check the box below.
Settings -> Experimental -> Enable Navigation Editor
Then add the dependency for Navigation Component to your build.gradle file
After you have added your dependency you need to create your Navigation Graph. To create your graph right click on res folder and go to
New->Android Resource File
After this you can open the Navigation Editor by clicking on the new resource file you have just created. Last step in setting up basic navigation is creating a NavHostFragment in your activity_main.xml.
Navigation Editor
Now that we have finished setting up the requirements, let’s take a look at our Navigation Editor. Click on your newly added nav_graph, this will open up the Navigation Editor. You can see that it’s currently empty, let’s change that! Click on add destination button from top left to start adding destinations to our Navigation Editor. Destinations are the places you can navigate to using your navigation controller. Let’s start by adding our home fragment and details fragment. (You can find the code using the GitHub link for the tutorial.) For the destinations to have a preview resource you can go ahead and add their xml resources to your individual fragments in the nav-graph.
tools:layout="@layout/resource_file"
Now that we have two destinations to navigate between let’s add our first action. Actions allow you to connect two destinations and will show up as an arrow in between your two destinations, which makes understanding your apps navigation flow much easier. You can add an action by hovering over a destination, clicking on the action connection circle and while still holding, dragging your cursor over the destination you want users to navigate to, and then releasing.
Something to note when using the Navigation Editor is that sometimes when you open up android studio the destinations will get all messed up. This is expected as the positions of the destinations are not held in the code of your nav-graph.xml to avoid messing up git every time you position a destination. So do not waste time properly positioning your destinations as you can simply fix them after they get messed up by clicking the Auto-Arrange button from the top left in the Navigation Editor.
Navigating Between Fragments
Now that we have added the action in our Navigation Editor, we need to wire it up with the navigation controller for this navigation graph for the navigation to work. Navigation Controller is the class that allows you to navigate in a navigation graph. Let’s create our Navigation Controller in our MainActivity class.
Now that we have a reference for our navController that we can use to navigate in HomeFragment, let’s add an onClickListener to our button in HomeFragment for navigating to the DetailsFragment. Let’s say that we also want to pass a string from HomeFragment to the DetailsFragment while navigating. There are two methods for achieving this. Using SafeArgs or using Bundles. I will be using the second method for this tutorial.
Navigation Controller’s navigate method allows us to navigate using an action or directly navigate to a destination using the id values in your nav-graph. We can also pass a bundle to the destination fragment and give a NavigationOptions object as the third parameter to set extra options for this navigation such as setting a specific destination in the back stack which the user will return after pressing the back button using setPopUpTo.
Of course after putting the string value to our Bundle we need to get the string in the DetailsFragment.
And this is it! You don’t have to do anything else. Android Navigation Component handles the rest including the backstack. Since we have finished our first navigation, let’s get to the more specific stuff!
How to Implement the Bottom Navigation Bar using Navigation Component
Bottom Navigation Views are almost always included in single activity apps. Now let’s implement as it is made really easy to do so by Android Navigation Component. First thing is first we need to add a menu resource.
The next thing we have to do is to fill our menu with items. Be aware that the id values of these items need to be the same with the destination ids we are going to add to our nav-graph after this for navigation to work.
Now let’s add a Bottom Navigation View to our activity_main.xml file.
The next step is adding the destinations to our nav-graph. Following the previously described steps add settings and profile fragments as destinations to in our Navigation Editor. We should now have a Navigation Editor looking like this.
The final step in wiring up our Bottom Navigation Bar to the Nav controller is adding the following line to the onCreate method of our MainActivity.java, where the first argument is your Bottom Navigation View and the second argument is your Navigation Controller.
NavigationUI.setupWithNavController(binding.mainBottomNavigation, navHostFragment.navController)
This will automatically setup the navigation for you and again you don’t have to do anything else for the navigation to work!
How to Implement Deep Links Using Navigation Component
Deep links are URLs that take users directly to specific content in your app. In Android, you can set up deep links by adding intent filters and extracting data from incoming intents to drive users to the right activity. However this sometimes gets really complicated and frustrating. Navigation Component makes deep linking a lot more easier.
Let’s start by adding a deep link to our DetailsFragment destination in the Navigation Editor. You can do this by simply clicking on the destination and clicking add a new deep link in the attributes screen. This will show you a pop up where you need to put in a URL for your deeplink. Let’s make this URL
https://navigation.tutorial/{passed_string}
for this tutorial. There are a few things to note here. Curly brackets in this link allows us to directly pass a parameter to our destination which you can use by calling
arguments!!.getString("passed_string")
Which is simply amazing and makes implementing deep links a breeze. Another thing to note is that chaining up parameters like
https://navigation.tutorial/{parameter1}/{parameter2}
Will not give you two separate key values. You will only get 1 parameter that you can access using “parameter1” as the key that will return the whole string after https://navigation.tutorial/ which you can then separate and use.
The next thing we have to do to set up deep linking is to add our nav-graph to our AndroidManifest.xml which will get us rid of adding intent-filters manually! Doing this will add all your deep links in that nav-graph automatically.
And that is it! You can test your new deep link by writing the following link in whatsapp to any conversation and then clicking on it.
https://navigation.tutorial/testString
Final Words
I hope you enjoyed this read. Any feedback is appreciated. Even tough there are still some problems with the Android Navigation Component the easy management of your app navigation flow and simplified deep links are worth it to switch to Navigation Component in my opinion as the features will only get better over time.
📝 Read this story later in Journal.
🗞 Wake up every Sunday morning to the week’s most noteworthy Tech stories, opinions, and news waiting in your inbox: Get the noteworthy newsletter >