Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Multiple Agument to fragment using TypeSafe in Navigation

I know it is possible to pass a single argument using Action in the source fragment

  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 get that in the destination fragment as specified in android docs

    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()
}

please let me know is there any way to pass multiple arguments in TypeSafe way

like image 865
Asgar Ahmed Avatar asked Jan 17 '26 08:01

Asgar Ahmed


1 Answers

Yes, you could do it by defining multiple arguments for your fragment in the Navigation graph and then pass them to the action in your code. This is an example:

navigation.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/navigation"
    app:startDestination="@id/firstFragment">
    <fragment
        android:id="@+id/firstFragment"
        android:name="com.example.app.FirstFragment"
        android:label="FirstFragment"
        tools:layout="@layout/fragment_first">
        <action
            android:id="@+id/action_firstFragment_to_secondFragment"
            app:destination="@id/secondFragment"
            app:enterAnim="@anim/slide_in_right"
            app:popExitAnim="@anim/slide_out_left" />
    </fragment>
    <fragment
        android:id="@+id/secondFragment"
        android:name="com.example.app.SecondFragment"
        android:label="secondFragment"
        tools:layout="@layout/fragment_second">
        <argument
            android:name="firstDataList"
            app:argType="com.example.app.domain.FirstData[]" />
        <argument
            android:name="secondDataList"
            app:argType="com.example.app.domain.SecondData[]" />

        <argument
            android:name="isOkey"
            app:argType="boolean" />
        <argument
            android:name="myString"
            app:argType="string" />
    </fragment>


</navigation>

and then in your code:

You should pass the arguments respectively as it is navigation.xml

FirstFragment.kt

findNavController().navigate(
    FirstFragmentDirections.actionFirstFragmentToSecondFragment(
        firstDataList.toTypedArray(),
        secondDataList.toTypedArray(),
        isOkey,
        myString
    )

And then retrieve it at the destination as a bundle like so:

SecondFragment.kt

val args = arguments?.let {
    SecondFragmentArgs.fromBundle(
        it
    )
}
if (args != null) {
    firstDataList = args.firstDataList.toCollection(ArrayList())
    secondDataList = args.secondDataList.toCollection(ArrayList())
    isOkey = args.isOkey
    myString = args.myString

}

To pass complex objects you should make them parcelable. In my example, I passed two lists of complex models that I parcelized them like this:

DataModels.kt

@Parcelize
data class FirstData(var id: Int, var color: Int = 0) : Parcelable

@Parcelize
data class SecondData(var name: String, var position: ArrayList<Int>) : Parcelable
like image 59
Squti Avatar answered Jan 20 '26 01:01

Squti