Search code examples
androidkotlinandroid-jetpack-navigation

How to transfer data from one Fragment to another?


I am writing an application on Kotlin (Android Studio), using jetpack.navigation architecture. There are two fragments: The first contains a list with class instances, which I display in the RecyclerView, the second for EditText (I fill in the client data). I also use Livedata and ViewModel. The problem is that when I go to the second fragment, fill in the data and confirm, I go to the 1st fragment. As I understand it, the following lines destroy the old Fragment1, and create a new one. the list on the first fragment is reset to zero (although the list is saved when you rotate the screen and minimize the application).

 val client = Clients(id,name,secondName,thirdName, address, creditCard, bankNum)
 val action = Fragment2Directions.actionFragment2ToFragment1(client)
 findNavController().navigate(action)

I could not find how to solve problem using the navigation component. I will be very grateful.


Solution

  • To pass data between two fragments with jetpack navigation you have to use Safe Args

    pass an argument section like

     <fragment android:id="@+id/myFragment" >
         <argument
             android:name="myArg"
             app:argType="integer"
             android:defaultValue="0" />
     </fragment>
    

    add classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" in top level gradle file

    and add the plugin apply plugin: "androidx.navigation.safeargs.kotlin" now send the value like so

    override fun onClick(v: View) {
       val amountTv: EditText = view!!.findViewById(R.id.editTextAmount)
       val amount = amountTv.text.toString().toInt()
       val action = SpecifyAmountFragmentDirections.confirmationAction(amount)
       v.findNavController().navigate(action)
    }
    
    

    and receive it as

    val args: ConfirmationFragmentArgs by navArgs()
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val tv: TextView = view.findViewById(R.id.textViewAmount)
        val amount = args.amount
        tv.text = amount.toString()
    }
    
    

    However safeargs works only for primitive types so you have to deconstruct and reconstruct if you're trying to pass Objects