Updated 29 April 2022
The interactions that allow users to travel through, into, and out of the various pieces of content within your app are referred to as navigation. The component of Android Jetpack navigation assists you in implementing navigation.
The Jetpack Navigation component depends on the below-mentioned parts:
Navigation Graph: A navigation graph is an XML resource that contains all navigation-related information in one place. This includes all of your app’s individual content areas, known as destinations, as well as the various paths a user can take through your app.
NavHost: A container that is empty and displays destinations from your navigation graph. The Navigation component includes a NavHost implementation by default, NavHostFragment, which displays fragment destinations.
NavController: A NavHost object that manages app navigation. As users move through your app, the NavController orchestrates the swapping of destination content in the NavHost.
As you navigate through your app, you tell the NavController
that you want to navigate either along a specific path in your navigation graph or directly to a specific destination. The NavController
then shows the appropriate destination in the NavHost
.
The Navigation part gives various different advantages, including the mentioned below:
In your build.gradle (module-level) file
1 2 3 |
def nav_version = "2.4.2" implementation("androidx.navigation:navigation-fragment-ktx:$nav_version") implementation("androidx.navigation:navigation-ui-ktx:$nav_version") |
In your build.gradle (app level) file OPTIONAL for safe_args
1 |
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.4.2") |
Also, add a plugin in your module-level build.gradle file for safe args
1 |
id("androidx.navigation.safeargs.kotlin") |
To add a navigation graph to your project, do the following:
res
directory and select New > Android Resource File. The New Resource File dialog appears.When you add your first navigation graph, Android Studio creates a navigation
resource directory within the res
directory. This directory contains your navigation graph resource file (nav_graph.xml
, for example).
for reference, check this screenshot
From the below code we will add a NavHostFragment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" /> </androidx.constraintlayout.widget.ConstraintLayout> |
For the demo, we have added 2 fragments Fragment A and Fragment B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
<?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/nav_graph" app:startDestination="@id/fragmentA"> <fragment android:id="@+id/fragmentA" android:name="com.example.androidnavigation.FragmentA" android:label="fragment_a" tools:layout="@layout/fragment_a"> <action android:id="@+id/pass_string" app:destination="@id/fragmentB"> <argument android:name="stringDemo" android:defaultValue="EMPTY" app:argType="string" app:nullable="true" /> </action> <action android:id="@+id/pass_user" app:destination="@id/fragmentB"> <argument android:name="userData" app:argType="com.example.androidnavigation.UserData" app:nullable="true" /> </action> <action android:id="@+id/pass_both" app:destination="@id/fragmentB"> <argument android:name="userData" app:argType="com.example.androidnavigation.UserData" app:nullable="true" /> </action> </fragment> <fragment android:id="@+id/fragmentB" android:name="com.example.androidnavigation.FragmentB" android:label="fragment_b" tools:layout="@layout/fragment_b"> <argument android:name="stringDemo" android:defaultValue="EMPTY" app:nullable="true" app:argType="string" /> <argument android:name="userData" app:nullable="true" android:defaultValue="@null" app:argType="com.example.androidnavigation.UserData" /> </fragment> </navigation> |
Here you can check that we have added some action from fragment A to Frgament B with argumnets
Here, is our Fragment A
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
class FragmentA : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_a, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val btn1 = view.findViewById<MaterialButton>(R.id.button1) val btn2 = view.findViewById<MaterialButton>(R.id.button2) val btn3 = view.findViewById<MaterialButton>(R.id.button3) btn1.setOnClickListener { findNavController().navigate(FragmentADirections.passString("Hello Arguments Received")) } btn2.setOnClickListener { findNavController().navigate(FragmentADirections.passUser(UserData())) } btn3.setOnClickListener { findNavController().navigate( FragmentADirections.passBoth( UserData(), "Arguments Received" ) ) } } } |
As a result, we move to fragment B with the passed arguments.
Here, is our Fragmet B
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class FragmentB : Fragment() { val args: FragmentBArgs by navArgs() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_b, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val argsText = view.findViewById<TextView>(R.id.stringText) val userText = view.findViewById<TextView>(R.id.userText) argsText.text = args.stringDemo if (args.userData != null) userText.text = "${args.userData?.userId}\n${args.userData?.userName}\n${args.userData?.userEmail}" } } |
Here is our UserData data class
1 2 3 |
import java.io.Serializable data class UserData(var userName: String = "Demo", val userId: String = "1", var userEmail: String = "[email protected]"):Serializable |
Note:- Please make your data class Serializable or Parcelable if you want to pass this as an argument
In the above example, you can see that we are passing some data from Fragment A to Fragment B
From btn1:- We are just passing a string value
For results check this screenshot
From btn2:- We are just passing User Details with a null string
For results check this screenshot
Note: Here you can see that “EMPTY” is visible for the string argument which we have passed as a default value in our navigation graph.
From btn3:- We are passing both string and User Details with this action
For results check this screenshot
For more details, please check this link
Hopefully, this blog will be helpful to you. If you have any queries, please write them in the comment section.
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
Be the first to comment.