How to Pass Data to Destination using Safe Args in Android? - GeeksforGeeks

04 Feb, 2021
SafeArgs is a gradle plugin that allows you to Pass data to destination UI components. It generates simple object and builder classes for type-safe navigation and access to any associated arguments. Safe Args is strongly recommended for navigating and passing data because it ensures type-safety. A sample video is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Kotlin language. 
Step 1: Create a new project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language.
Step 2: Add dependency
Inside build.gradle (project) add the following code under dependencies.
 dependencies {
    classpath “androidx.navigation:navigation-safe-args-gradle-plugin:2.3.2”
}
Inside build.gradle (app) add the following code and click Sync now
plugins {
   id ‘com.android.application’
   id ‘kotlin-android’
   id ‘kotlin-android-extensions’
   id “androidx.navigation.safeargs.kotlin”
}
Step 3: Create two new Fragments
In this article, we are going to send data from one fragment and receive it in another. So, First, create two Fragments. To create a new Fragment:
Project Name (right click) -> new -> Fragment -> Fragment (Blank)
A dialog box will open. In the Fragment Name write Registration and in fragment layout name write fragment_registration. In a similar way create another fragment with fragment name Detail and fragment layout name as fragment_detail.
Step 4: Create an XML layout of both fragments
Go to the Fragment_registration.xml file and refer to the following code. Below is the code for the Fragment_registration.xml file. This is for the basic layout used in the app.
XML
<?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=".Registration">      <EditText        android:id="@+id/et_name"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentStart="true"        android:layout_alignParentEnd="true"        android:layout_margin="20dp"        android:ems="10"        android:hint="Name"        android:inputType="textPersonName"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toTopOf="parent" />      <EditText        android:id="@+id/et_email"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:ems="10"        android:hint="Email"        android:layout_margin="20dp"        android:inputType="textPersonName"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/et_name" />      <EditText        android:id="@+id/et_password"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:ems="10"        android:hint="Password"        android:layout_margin="20dp"        android:inputType="textPersonName"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/et_email" />      <Button        android:id="@+id/button_send"        android:layout_width="276dp"        android:layout_height="50dp"        android:text="Send"        android:layout_margin="20dp"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/et_password" />    </androidx.constraintlayout.widget.ConstraintLayout>
Go to the Fragment_detail.xml file and refer to the following code. Below is the code for the Fragment_detail.xml file. 
XML
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    xmlns:app="http://schemas.android.com/apk/res-auto"    tools:context=".Details">   <TextView     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:text="Name :"     android:id="@+id/tv1"     android:textSize="20sp"     app:layout_constraintLeft_toLeftOf="parent"     app:layout_constraintTop_toTopOf="parent"     android:layout_marginTop="50dp"     android:layout_marginStart="30dp"     />      <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="20sp"        android:textColor="@color/black"        android:id="@+id/tv_name"        app:layout_constraintLeft_toRightOf="@id/tv1"        app:layout_constraintTop_toTopOf="@id/tv1"        android:layout_marginStart="20dp"        />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Email :"        android:id="@+id/tv2"        android:textSize="20sp"        app:layout_constraintTop_toBottomOf="@id/tv1"        app:layout_constraintLeft_toLeftOf="parent"        android:layout_marginTop="20dp"        android:layout_marginStart="30dp"        />      <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="20sp"        android:textColor="@color/black"        android:id="@+id/tv_email"        app:layout_constraintLeft_toRightOf="@id/tv2"        app:layout_constraintTop_toTopOf="@id/tv2"        android:layout_marginStart="20dp"        />      <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Password :"        android:id="@+id/tv3"        android:textSize="20sp"        app:layout_constraintTop_toBottomOf="@id/tv2"        app:layout_constraintLeft_toLeftOf="parent"        android:layout_marginTop="20dp"        android:layout_marginStart="30dp"        />      <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="20sp"        android:textColor="@color/black"        android:id="@+id/tv_password"        app:layout_constraintLeft_toRightOf="@id/tv3"        app:layout_constraintTop_toTopOf="@id/tv3"        android:layout_marginStart="20dp"        />  </androidx.constraintlayout.widget.ConstraintLayout>
Step 5: Create a new Kotlin class 
Create a new Class User.kt we will use data of custom generic “User” having a name, email, password to pass to another fragment.
Kotlin
import android.os.Parcelableimport kotlinx.android.parcel.Parcelize  @Parcelizedata class User(    val name : String ="",    val email : String= "",    val password : String =""  ) : Parcelable
Step 6: Create a new Navigation graph
res (right click) -> new -> Android resource file 
In the dialog write file name as nav_graph and choose Resource type as “Navigation“. and click Ok. Now open the just created nav_graph.xml file click on the new destination icon and choose both of the fragments. Make Fragment_registration as the home. Create action from fragment_registration to fragment_detail and pass the User argument in the arguments of Fragment_detail. Its XML code is given below.
XML
<?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/registration">      <fragment        android:id="@+id/registration"        android:name="com.geeksforgeeks.navargsexample.Registration"        android:label="fragment_registration"        tools:layout="@layout/fragment_registration" >        <action            android:id="@+id/action_registration_to_details"            app:destination="@id/details" />    </fragment>      <fragment        android:id="@+id/details"        android:name="com.geeksforgeeks.navargsexample.Details"        android:label="fragment_details"        tools:layout="@layout/fragment_details" >        <argument            android:name="user"            app:argType="com.geeksforgeeks.navargsexample.User" />    </fragment>  </navigation>
Step 7: Working with the activity_main.xml file
Go to the activity_main.xml file and refer to the following code. Below is the code for the activity_main.xml file. This layout contains one Frame Layout and a fragment that will act as a host for the fragments that we created earlier. Notice the navGraph tag inside the fragment tag.
XML
<?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">      <FrameLayout        android:id="@+id/frameLayout"        android:layout_width="match_parent"        android:layout_height="0dp"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintHorizontal_bias="0.5"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toTopOf="parent">                <!--this fragmnet will act as the host for             both fragments in the main activity-->        <fragment            android:id="@+id/nav_Host_Fragment"            android:name="androidx.navigation.fragment.NavHostFragment"            android:layout_width="match_parent"            android:layout_height="match_parent"            app:defaultNavHost="true"            app:navGraph="@navigation/nav_graph"             />      </FrameLayout>  </androidx.constraintlayout.widget.ConstraintLayout>
Step 8: Working with Registration.kt file
Go to the Registration.kt file and refer to the following code. Below is the code for the Registration.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin
import android.os.Bundleimport androidx.fragment.app.Fragmentimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport androidx.navigation.fragment.findNavControllerimport com.geeksforgeeks.navargsexample.databinding.FragmentRegistrationBinding  class Registration : Fragment() {      private var _binding: FragmentRegistrationBinding? = null    private val binding get() = _binding!!      override fun onCreateView(        inflater: LayoutInflater, container: ViewGroup?,        savedInstanceState: Bundle?    ): View {        _binding = FragmentRegistrationBinding.inflate(inflater, container, false)        val view = binding.root          // call onClick on the SendButton        binding.buttonSend.setOnClickListener {            val name = binding.etName.text.toString()            val email = binding.etEmail.text.toString()            val password = binding.etPassword.text.toString()                          // create user object and pass the               // required arguments            // that is name, email,and password            val user = User(name,email, password)                          // create an action and pass the the required user object to it            // If you can not find the RegistrationDirection try to "Build project"            val action = RegistrationDirections.actionRegistrationToDetails(user)                          // this will navigate the current fragment i.e               // Registration to the Detail fragment            findNavController().navigate(                action            )        }        return view    }      override fun onDestroyView() {        super.onDestroyView()        _binding = null    }}
Step 9: Working with the Details.kt file
Go to the Details.kt file and refer to the following code. Below is the code for the Details.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin
import android.os.Bundleimport androidx.fragment.app.Fragmentimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport androidx.navigation.fragment.navArgsimport com.geeksforgeeks.navargsexample.databinding.FragmentDetailsBinding  class Details : Fragment() {      private var _binding: FragmentDetailsBinding? = null    private val binding get() = _binding!!      // get the arguments from the Registration fragment    private val args : DetailsArgs by navArgs()      override fun onCreateView(        inflater: LayoutInflater, container: ViewGroup?,        savedInstanceState: Bundle?    ): View {        _binding = FragmentDetailsBinding.inflate(inflater, container, false)        val view = binding.root          // Receive the arguments in a variable        val userDetails = args.user                // set the values to respective textViews        binding.tvName.text = userDetails.name        binding.tvEmail.text = userDetails.email        binding.tvPassword.text = userDetails.password          return view    }      override fun onDestroyView() {        super.onDestroyView()        _binding = null    }}
Note: In this example, we don’t have to write any code inside ActivityMain.kt
Github Repo here.
android
Android
Kotlin
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
How to Create and Add Data to SQLite Database in Android?
Services in Android with Example
Broadcast Receiver in Android With Example
Content Providers in Android with Example
Android RecyclerView in Kotlin
Services in Android with Example
Broadcast Receiver in Android With Example
Content Providers in Android with Example
Android RecyclerView in Kotlin
Android UI Layouts