<p>This post is about how to pass data between destinations using Android Jetpack Navigation.</p> 
 
 
 
<div class="wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-a89b3969 wp-block-buttons-is-layout-flex"> 
<div class="wp-block-button"><a class="wp-block-button__link has-white-color has-text-color has-background" style="background-color: #190374;" href="https://github.com/arunk7839/PassDataWithNavigation"><strong>DOWNLOAD CODE</strong></a></div> 
</div> 
 
 
 
<h4> </h4> 
<h3><span style="color: #000080;"><strong>Use Safe Args to pass data</strong></span></h3> 
<p>The Navigation component has a Gradle plugin called <strong><span style="color: #008000;">Safe Args</span> </strong>that generates simple object and builder classes that enable type-safe navigation and argument passing between destinations.</p> 
<p>Safe Args is strongly recommended for navigating and passing data, because it ensures type-safety.</p> 
<h3><span style="color: #000080;"><strong>Creating new project</strong></span></h3> 
<p>1 . Create a new project by going to <span style="color: #008000;"><strong>File ⇒ New Android Project</strong></span>, select <span style="color: #008000;"><strong>Empty</strong></span> Activity, provide <span style="color: #008000;"><strong>app</strong></span> name, select language to <span style="color: #008000;"><strong>kotlin</strong></span> and then finally click on <span style="color: #0000ff;"><strong>finish</strong></span>.</p> 
<p>2 . Open app-level build.gradle file and under the <span style="color: #008000;"><strong>dependencies</strong></span> section add the below libraries and then sync the project<strong>:</strong></p> 
<p><span style="color: #0000ff;"><strong>build.gradle</strong></span></p> 
<pre>dependencies {<br /><strong><span style="color: #008000;"> // jetpack navigation dependency </span></strong><br /> implementation("androidx.navigation:navigation-fragment-ktx:2.4.1")<br /> implementation("androidx.navigation:navigation-ui-ktx:2.4.1")<br />}</pre> 
<p>3. To add <strong><a href="https://developer.android.com/topic/libraries/architecture/navigation/navigation-pass-data#Safe-args">Safe Args</a></strong> to your project, requires an additional plugin and one more classpath dependency:</p> 
<ul> 
<li>Open app-level build.gradle file and add the below <span style="color: #333333;">plugin</span> under <strong><span style="color: #008000;">plugins</span></strong> section:</li> 
</ul> 
<pre>plugins {<br /> id 'androidx.navigation.safeargs.kotlin'<br />}</pre> 
<ul> 
<li>Open project-level build.gradle file, include the following <span style="color: #333333;">classpath, and then click on </span><strong><span style="color: #008000;">Sync Now</span></strong>:</li> 
</ul> 
<pre>classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.4.1"</pre> 
<h4 id="add-navhost" role="presentation" data-text="Add a NavHost to an activity"><span style="color: #000080;"><strong>Add a NavHostFragment via XML</strong></span></h4> 
<p>4. The below XML file shows a <strong><span style="color: #008000;">NavHostFragment</span></strong> as part of an app’s main activity:</p> 
<p><strong><span style="color: #008000;">activity_main.xml</span></strong></p> 
<pre><;?xml version="1.0" encoding="utf-8"?>;<br /><;androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> xmlns:app="http://schemas.android.com/apk/res-auto"<br /> xmlns:tools="http://schemas.android.com/tools"<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> tools:context=".MainActivity">;<br /><br /> <;fragment<br /> android:id="@+id/nav_host_fragment"<br /> android:name="androidx.navigation.fragment.NavHostFragment"<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> app:defaultNavHost="true"<br /> app:layout_constraintBottom_toBottomOf="parent"<br /> app:layout_constraintEnd_toEndOf="parent"<br /> app:layout_constraintStart_toStartOf="parent"<br /> app:layout_constraintTop_toTopOf="parent"<br /> app:navGraph="@navigation/nav_graph" />;<br /><br /><;/androidx.constraintlayout.widget.ConstraintLayout>;</pre> 
<ul> 
<li><strong><span style="color: #0000ff;">android:name</span>: </strong>attribute contains the class name of your NavHost implementation.</li> 
<li><span style="color: #0000ff;"><strong>app:navGraph:</strong></span> defines which Navigation Graph will be associated with the Navigation Host.</li> 
<li><span style="color: #0000ff;"><strong>app:defaultNavHost=”true”:</strong></span> ensures that the Navigation Host intercepts the system back button when pressed.</li> 
</ul> 
<p>5. Let’s create two empty fragments i.e. FragmentA and FragmentB which we will add to nav_graph as destinations.</p> 
<h4 id="add-navhost" role="presentation" data-text="Add a NavHost to an activity"><span style="color: #000080;"><strong><span class="devsite-heading" role="heading" aria-level="2">Add a Navigation graph</span></strong></span></h4> 
<p>6. Right-click on the <span style="color: #008000;"><strong>res</strong></span> directory and choose <strong><span style="color: #008000;">New ->; Android resource file</span>.</strong> Set the title for the file and choose <span style="color: #008000;"><strong>Navigation</strong></span> from the <span style="color: #008000;"><strong>Resource type</strong></span> dropdown and then click on <span style="color: #008000;"><strong>ok</strong></span>.</p> 
<p>7. The below layout file defines the Navigation Graph.</p> 
<p><span style="color: #0000ff;"><strong>nav_graph.xml</strong></span></p> 
<pre><;?xml version="1.0" encoding="utf-8"?>;<br /><;navigation xmlns:android="http://schemas.android.com/apk/res/android"<br /> xmlns:app="http://schemas.android.com/apk/res-auto"<br /> xmlns:tools="http://schemas.android.com/tools"<br /> android:id="@+id/nav_graph"<br /> app:startDestination="@id/fragmentA">;<br /><br /> <;fragment<br /> android:id="@+id/fragmentA"<br /> android:name="com.c1ctech.passdatawithnavigation.FragmentA"<br /> android:label="FragmentA"<br /> tools:layout="@layout/fragment_a">;<br /><br /><strong><span style="color: #008000;"> <;action</span></strong><br /><strong><span style="color: #008000;"> android:id="@+id/action_fragmentA_to_fragmentB"</span></strong><br /><strong><span style="color: #008000;"> app:destination="@id/fragmentB" />;</span></strong><br /><br /> <;/fragment>;<br /><br /> <;fragment<br /> android:id="@+id/fragmentB"<br /> android:name="com.c1ctech.passdatawithnavigation.FragmentB"<br /> android:label="FragmentB"<br /> tools:layout="@layout/fragment_b">;<br /><br /> <strong><span style="color: #008000;"> <;argument</span></strong><br /><strong><span style="color: #008000;"> android:name="data"</span></strong><br /><strong><span style="color: #008000;"> android:defaultValue="defaultValue"</span></strong><br /><strong><span style="color: #008000;"> app:argType="string" />;</span></strong><br /><br /> <;/fragment>;<br /><;/navigation>;</pre> 
<ul> 
<li><strong><span style="color: #0000ff;">app:startDestination</span>: </strong>defines the starting destination. </li> 
<li><strong><span style="color: #0000ff;">android:name:</span> </strong>shows the name of the fragment that is associated with the destination.</li> 
<li><strong><span style="color: #0000ff;">android:label:</span> </strong>contains the user-readable name of the destination.</li> 
<li><strong><span style="color: #0000ff;">tools:layout:</span> </strong>defines the layout of the destination.</li> 
</ul> 
<h5><span style="color: #000080;"><strong>Add action and arguments</strong></span></h5> 
<p><span style="color: #0000ff;"><strong>Action</strong></span></p> 
<p>In the navigation graph using actions connect both fragments from FragmentA to FragmentB, with a unique ID.</p> 
<p><span style="color: #0000ff;"><strong>Arguments</strong></span></p> 
<p>FragmentB will receive data from FragmentA, so we have to add an argument to FragmentB.</p>
<!-- WP QUADS Content Ad Plugin v. 2.0.98.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>
 
<p>In the navigation graph select FragmentB and from the right side window click the + button in Arguments to add one. Provide argument name, type, default value, and then click on <span style="color: #008000;"><strong>Add</strong></span>.</p> 
<p>After adding the argument, rebuild the project. Now inside the <strong><span style="color: #008000;">navigation-args</span></strong> folder you can see the generated classes using which we will pass data between destinations.</p> 
<p><img class="alignnone size-full wp-image-3167" src="https://c1ctech.com/wp-content/uploads/2022/04/app.png" alt="" width="424" height="361" /></p> 
<h4><span style="color: #000080;"><strong>Creating Fragment&#8217;s layout file</strong></span></h4> 
<p>8. The fragment_a.xml and fragment_b.xml define the layout file of Fragments.</p> 
<p><strong><span style="color: #0000ff;">fragment_a.xml</span></strong></p> 
<pre><;?xml version="1.0" encoding="utf-8"?>;<br /><;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> xmlns:tools="http://schemas.android.com/tools"<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> tools:context=".FragmentA">;<br /><br /> <;TextView<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> android:gravity="center"<br /> android:text="FragmentA"<br /> android:textSize="30sp"/>;<br /><br /> <;Button<br /> android:id="@+id/btnGotoFragmentB"<br /> android:layout_width="wrap_content"<br /> android:layout_height="wrap_content"<br /> android:layout_gravity="center_horizontal|bottom"<br /> android:text="Goto FragmentB"<br /> android:textAllCaps="false" />;<br /><br /><;/FrameLayout>;</pre> 
<p><strong><span style="color: #0000ff;">fragment_b.xml</span></strong></p> 
<pre><;?xml version="1.0" encoding="utf-8"?>;<br /><;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> xmlns:tools="http://schemas.android.com/tools"<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> tools:context=".FragmentB">;<br /><br /> <;TextView<br /> android:id="@+id/tvFragmentB"<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> android:gravity="center"<br /> android:textSize="30sp" />;<br /><br /><;/FrameLayout>;</pre> 
<h4><span style="color: #000080;"><strong>Creating Fragment&#8217;s kotlin file</strong></span></h4> 
<p>9. The FragmentA.kt and FragmentB.kt define the two fragments kotlin file.</p> 
<p>Open <strong><span style="color: #008000;">FragmentA.kt</span></strong> file and add the below code:</p> 
<p><strong><span style="color: #0000ff;">FragmentA.kt </span></strong></p> 
<pre>package com.c1ctech.passdatawithnavigation<br /><br />import android.os.Bundle<br />import android.view.LayoutInflater<br />import android.view.View<br />import android.view.ViewGroup<br />import android.widget.Button<br />import androidx.fragment.app.Fragment<br />import androidx.navigation.findNavController<br /><br />class FragmentA : Fragment() {<br /><br /> override fun onCreateView(<br /> inflater: LayoutInflater, container: ViewGroup?,<br /> savedInstanceState: Bundle?<br /> ): View? {<br /><strong><span style="color: #008000;"> // Inflate the layout for this fragment</span></strong><br /> return inflater.inflate(R.layout.fragment_a, container, false)<br /> }<br /><br /> override fun onViewCreated(view: View, savedInstanceState: Bundle?) {<br /> super.onViewCreated(view, savedInstanceState)<br /> val navController = view.findNavController()<br /> val button = view.findViewById<;Button>;(R.id.btnGotoFragmentB)<br /> button.setOnClickListener {<br /> <strong><span style="color: #008000;"> val action = FragmentADirections.actionFragmentAToFragmentB("FragmentB")</span></strong><br /><strong><span style="color: #008000;"> navController.navigate(action)</span></strong><br /> }<br /> }<br />}</pre> 
<ul> 
<li>The generated class <span style="color: #008000;"><strong>FragmentADirections</strong></span> for FragmentA internally sets the value &#8220;FragmentB&#8221; to the argument of the name &#8220;data&#8221; we have created for FragmentB.</li> 
</ul> 
<p>Open <span style="color: #008000;"><strong>FragmentB.kt</strong></span> file and add the below code:</p> 
<p><strong><span style="color: #0000ff;">FragmentB.kt </span></strong></p> 
<pre>package com.c1ctech.passdatawithnavigation<br /><br />import android.os.Bundle<br />import androidx.fragment.app.Fragment<br />import android.view.LayoutInflater<br />import android.view.View<br />import android.view.ViewGroup<br />import android.widget.TextView<br /><br />class FragmentB : Fragment() {<br /> private var DATA = ""<br /><br /> override fun onCreate(savedInstanceState: Bundle?) {<br /> super.onCreate(savedInstanceState)<br /> <strong><span style="color: #008000;">val args = FragmentBArgs.fromBundle(requireArguments())</span></strong><br /><strong><span style="color: #008000;"> DATA = args.data</span></strong><br /> }<br /><br /> override fun onCreateView(<br /> inflater: LayoutInflater, container: ViewGroup?,<br /> savedInstanceState: Bundle?<br /> ): View? {<br /> // Inflate the layout for this fragment<br /> return inflater.inflate(R.layout.fragment_b, container, false)<br /> }<br /><br /> override fun onViewCreated(view: View, savedInstanceState: Bundle?) {<br /> super.onViewCreated(view, savedInstanceState)<br /> val textView = view.findViewById<;TextView>;(R.id.tvFragmentB)<br /> textView.text = DATA<br /> }<br />}</pre> 
<ul> 
<li>Using the generated class <span style="color: #008000;"><strong>FragmentBArgs </strong></span>for FragmentB, we will get the value stored for the data argument.</li> 
</ul> 
<h4><span style="color: #000080;"><strong>Writing MainActivity Code</strong></span></h4> 
<p>10. The MainActivity file contains the below code:</p> 
<p><span style="color: #0000ff;"><strong>MainActivity.kt</strong></span></p> 
<pre>package com.c1ctech.passdatawithnavigation<br /><br />import androidx.appcompat.app.AppCompatActivity<br />import android.os.Bundle<br />import androidx.navigation.NavController<br />import androidx.navigation.findNavController<br />import androidx.navigation.ui.NavigationUI.setupActionBarWithNavController<br /><br />class MainActivity : AppCompatActivity() {<br /><br /> lateinit var navController: NavController<br /><br /> override fun onCreate(savedInstanceState: Bundle?) {<br /> super.onCreate(savedInstanceState)<br /> setContentView(R.layout.activity_main)<br /><br /> navController = this.findNavController(R.id.nav_host_fragment)<br /><br /> setupActionBarWithNavController(this, navController)<br /> }<br /><br /> override fun onSupportNavigateUp(): Boolean {<br /> navController.navigateUp()<br /> return super.onSupportNavigateUp()<br /> }<br />}</pre> 
<p>In the above code,</p> 
<ul> 
<li><span style="color: #0000ff;"><strong>this.findNavController()</strong></span> gives us the instance of NavController.</li> 
<li><span style="color: #0000ff;"><strong>setupActionBarWithNavController():</strong></span> Sets up the ActionBar returned by <span style="color: #008000;"><strong>AppCompatActivity.getSupportActionBar</strong></span> for use with a NavController.By calling this method, the title in the action bar will automatically be updated when the destination changes.</li> 
<li><span style="color: #0000ff;"><strong>onSupportNavigateUp():</strong> </span>This method is called whenever the user chooses to navigate Up within your application’s activity hierarchy from the action bar.</li> 
</ul> 
<p>When you run the app it will look like this:</p> 
<p><img class="alignnone wp-image-3159" src="https://c1ctech.com/wp-content/uploads/2022/04/Screenshot_2022-04-06-13-22-59-448_com.c1ctech.jetpacknavigation-473x1024.png" alt="" width="358" height="775" /> <img class="alignnone wp-image-3160" src="https://c1ctech.com/wp-content/uploads/2022/04/Screenshot_2022-04-06-13-23-07-863_com.c1ctech.jetpacknavigation-473x1024.png" alt="" width="358" height="775" /></p> 
<p> ;</p> 


