Implementing Navigation Architecture in Android
In this guide, we would implement the navigation architecture component in a simple Android app.
Before we begin, you should have:
- Basic of android development with java
- Laptop
- An Android IDE. I will be using Android studio version 2.0
- Migrated project to use AndroidX libraries. If not, see how to migrate your project here.
- Good spirits!
What’s with the Navigation Component
Navigation makes it possible for users to navigate in and out from the different parts of and within your app.
The Navigation component enables us to implement navigation through our app. It also guarantees a uniform and predictable user experience by complying with the principles of navigation.
Creating the project and adding the necessary dependencies
Step 1: Create a new project in android studio with an empty activity. Name it Navigation Sample.
Step 2: Set the minimum SDK to API 14 or higher.
Step 3: Create a new fragment with ViewModel. Name it “HomeFragment”. Make it the launcher activity.
Step 4: Add the following dependencies to your app’s build.gradle file to include Navigation support in your project:
def nav_version = "2.3.0"
// Java language implementation
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
Step 5: Add the Safe Args to your project include the following classpath in your top-level build.gradle file:
def nav_version = "2.3.0"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
Apply the plugin below in your app or module’s build.gradle file:
apply plugin: "androidx.navigation.safeargs"
NOTE: If you are using kotlin, you can find the alternative dependencies here.
Step 6: Sync your project.
Creating the Navigation Graph
The navigation graph is an XML file that describes how activities and fragments relate to each other and the ways a user can move between them. In the navigation graph, we define the actions to perform in moving and parsing data between destinations.
Step 1: Right-click on the res folder.
Step 2: Select Android Resource File from the menu option.
Step 3: Name the file “navigation_graph” and change the resource type to navigation.
Step 4: Click OK to create the file.
Declaring the Navigation Host Fragment
The navigation host fragment creates a container that allows destinations to be swapped in and out as the user navigates through the app.
Step 1: Go to your activity_main.xml file.
Step 2: Delete the default Hello World text view.
Step 3: Switch to design mode.
Step 4: From the palette select Containers.
Step 5: Select NavHostFragment.Drag and drop into the design tab.
Step 6: Select the navigation_graph.xml file you created earlier as the navigation graph.
Step 7: Click OK, to create the navigation host fragment.
Step 8: Change the id to nav_host_fragment
.
Step 9: Constraint the top, bottom, start, and end of the navigation host fragment to its parent.
Step 10: Set the layout height and width of the nav host fragment to 0dp(match constraint).
Adding destinations
We are going to add destinations to the navigation graph. A destination is a part of your app a user can go to.Every navigation graph must have its start destination. The start destination is the screen that appears when the user first launches the app. The fragment that has the home icon on it is the start destination of that navigation graph. We can either add fragments that already exist in your project or create new fragments using the navigation graph. Step 1: Switch to the design tab of your navigation graph. To add an existing fragment:
- Step 1: Click on “new destination”.
- Step 2: Select the fragment you wish to add. In our case, it’s the home_fragment.
To create a new fragment from the navigation graph:
- Step 1: Click on “new destination”.
- Step 2: Select the create new destination option.
- Step 3: Select a blank fragment and click next.
- Step 4: Name the fragment “SecondFragment”.
- Step 5: Click on the finish button.
This new fragment would appear as another destination in the navigation graph.
This is what the XML file of our nav graph would look like.
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation_graph"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.example.navigationsampleapp.HomeFragment"
android:label="home_fragment"
tools:layout="@layout/home_fragment"/>
<fragment
android:id="@+id/secondFragment"
android:name="com.example.navigationsampleapp.SecondFragment"
android:label="fragment_second"
tools:layout="@layout/fragment_second" />
</navigation>
We can see that by default the first fragment(HomeFragment) we added has made the start destination.
To choose a start destination:
Step 1: Select the destination by clicking on it.
Step 2: Right-click on the destination. Click on “Set as Start Destination”.
Adding actions
So far, our app doesn’t do anything, we are going to add actions to our app, and make it somewhat interactive. An action is a logical connection between destinations in our app. It represents paths users can take in navigating through your app.
Double-clicking on a fragment(destination) in a navigation graph design tab opens up that fragments XML file into the editor.
We are going to add a button in our first fragment, which when clicked on would take us to the second fragment.
Step 1: In your navigation graphs design tab, double click on the home_fragment. This would take you to the home_fragment.xml file.
Step 2: Switch to the Design tab. Delete the default hello world text view.
Step 3: Switch to the Design tab. Drag and drop a button from the palette on to the parent. Give it the title “Move to Next Fragment”.
Step 4: Position the button and give it an ID: next_fragment_button
.
Step 5: In the HomeFragment.java’s OnViewCreated method, implement the OnClick event of the button.
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button button = view.findViewById(R.id.next_fragment_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
We would reference an Action in the navigation graph in the onClick method of this button.
Step 6: In the navigation graph, take the cursor to the right-hand edge of the main fragment. Click on the circle that appears and drag on to the second fragment.
This is how an action is added to the navigation graph.
Step 7: Click on the action to select it. In the Attributes panel, rename the actions Id to “launch_second_fragment”.
We would refer to this action in the onClick method of the button we created earlier.
If you switch to the text tab of our navigation graph, you would see that an action tag has been added to the home_fragment
.
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation_graph"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="com.example.navigationsampleapp.HomeFragment"
android:label="home_fragment"
tools:layout="@layout/home_fragment" >
<action
android:id="@+id/launch_second_fragment"
app:destination="@id/secondFragment" />
</fragment>
<fragment
android:id="@+id/secondFragment"
android:name="com.example.navigationsampleapp.SecondFragment"
android:label="fragment_second"
tools:layout="@layout/fragment_second" />
</navigation>
Step 8: Rebuild the project to generate the necessary calls. To do this:
- In the toolbar, select Rebuild Project from the drop-down menu of the Build item.
You can find the newly generated calls in the generated Java directory. We would use this generated HomeFragmentDirection
s class to load the second fragment by calling the method launchSecondFragment
.
Step 9: In the buttons onClick method, Type in:
Navigation.findNavController(view).navigate(HomeFragmentDirections.launchSecondFragment());
findNavController()
accepts a view as a parameter. In this case, we passed in the view we received in the buttons onClick method.
Recall that launchSecondFragment was the id we gave to the action.
Whew! That was cool.
We have successfully implemented navigation using navigation architecture. In our next article, we will see how we can pass actions as arguments.
Happy Coding!