The Navigation Architecture Component simplifies navigation implementation while also assisting you in visualizing your app’s navigation flow. The library offers a variety of advantages, including:
- Handling of fragment transactions automatically
- By default, up and back actions are handled correctly.
- Default animation and transition behaviors
- Deep linking is regarded as a first-rate operation.
- Implementing navigation UI patterns (such as navigation drawers and bottom navigation) with minimal additional effort
- When navigating Android Studio tooling for visualizing and editing an app’s navigation flow, use type safety when passing information.
Overview
The Navigation Component is made up of three major parts:
- Navigation Graph (New XML resource) — This is a resource that collects all navigation-related data in one place. This includes all of the locations in your app, referred to as destinations, as well as the possible paths a user could take through your app.
- NavHostFragment (Layout XML view) — This is a unique widget that you can include in your layout. It shows various destinations from your Navigation Graph.
- NavController (Kotlin/Java object) — This is an object that keeps track of where you are in the navigation graph. As you move through a navigation graph, it orchestrates the swapping of destination content in the NavHostFragment.
Integration
Simply add the following code to the dependencies section of your module-level build.gradle file.
def nav_version = "2.2.1"
// The default implementations implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"
// The Kotlin ones implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
|
Graph of Navigation
First, we’ll make a file with our navigation graph in it. Create a new android resource file in the res directory as shown below.
Under the navigation directory, an empty resource file named nav graph.xml will be created.
For demonstration purposes, we have created a sample app with two fragments named FirstFragment and SecondFragment. We will navigate to the SecondFragment by clicking the button in the FirstFragment. In the navigation graph, we define these fragments as follows.
android:id = "@+id/gfg_graph"
app:startDestination = "@id/gfg_nav_holder" >
< fragment
android:id = "@+id/gfg_nav"
android:name = "app.navigationcomponentexample.FirstFragment"
tools:layout = "@layout/fragment_first" >
< action
android:id = "@+id/something_new"
app:destination = "@id/nav_second_fragment" />
</ fragment >
< fragment
android:id = "@+id/something2"
android:name = "app.navigationcomponentexample.SecondFragment"
tools:layout = "@layout/fragment_second" />
</ navigation >
|
The root tag navigation contains a parameter called app:startDestination, which contains the id of our first fragment. This specifies that the first fragment will be loaded automatically into the NavHostFragment. The concept of a destination is introduced in the Navigation Component. A destination is any location in your app that you can navigate to, typically a fragment or an activity. These are supported by default, but you can also create your own custom destination types if necessary. Take note that we defined an action with the following attributes for the first fragment:
android:id="@+id/gfg_first_frag" app:destination="@id/gfg_second_frag"
Each action should have a distinct id that we will use to navigate to the desired destination.
The destination here points to the id of the second fragment defined in the nav graph, indicating that we will navigate to the second fragment with this action.
Types of navigation
We can navigate in a variety of ways thanks to the navigation component.
Using the destination ID to navigate
To navigate to a destination fragment, we can provide its id, as shown below.
button.setOnClickListener { findNavController().navigate(R.id.gfg_fragment)
} |
The final step is to define the NavHostFragment. It is a special widget that displays the various destinations defined in the navigation graph. Copy and paste the following code into the layout of the activity where we want to load our FirstFragment.
< fragment
android:id = "@+id/gfgNavigation_host_gfgFragment"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:name = "androidx.gfgNavigationigation.gfgFragment.GfgNavigationHostGfgFragment"
app:gfgNavigationGraph = "@gfgNavigationigation/gfgNavigation_graph"
app:defaultGfgNavigationHost = "true" />
|
The NavHostFragment used by NavController is defined by the android:name=”androidx.navigation.fragment.NavHostFragment” attribute.
- app:defaultNavHost=”true” simply indicates that you want this to be the NavHost that intercepts and acts as your device’s back button.
- The NavHostFragment is associated with a navigation graph via app:navGraph=”@navigation/app navigation.” In this NavHostFragment, this navigation graph specifies all of the destinations to which the user can navigate.
- When you run the app after these steps, the FirstFragment should be loaded automatically, and clicking the button should open the SecondFragment. Also, pressing the back button should take you back to the FirstFragment.
That’s all. The Navigation Component is now operational. In the following section, we’ll go over how to safely navigate to fragments while passing arguments.
Arguments that are safe
Safe args is a Gradle plugin that generates simple object and builder classes for type-safe access to arguments specified for destinations and actions in the navigation component. The safe args plugin is now enabled in your project. We will add two arguments to the FirstFragment that will be passed to the SecondFragment. In the navigation graph, we will define arguments as follows.
Integration
The first argument, arg1, is of type Integer and has the default value of 0. Similarly, the second argument, arg2, is of type String and has the default value “default.” Gradle will generate a class named SecondFragmentArgs after we define these arguments, which can be used in SecondFragment to retrieve the arguments in the following manner:
val username = arguments?.getString("gfgCouseName") val username = args.username classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.2.1"
Conclusion
That’s all that’s needed to pass arguments in a type-safe way. Aside from the built-in types, you can define your own custom types of arguments by creating a Parcelable class.