Morozov
Morozov

Reputation: 5250

Transmit data with Jetpack

Looking for a more elegant way to transmit data with Jetpack

Now I am passing the data as follows:

override fun onListItemClick(itemIndex: Int, itemCode: String) {
        val bundle = Bundle()
        bundle.putString(KEY_TARGET_GUID, (adapter.getItem(itemIndex) as Target).guid)
        findNavController().navigate(R.id.target_edit, bundle)
    }

And get it in another fragment smth like this:

private val targetGuid: String
        get() = arguments?.getString(KEY_TARGET_GUID, "") ?: ""

I watched the guys at google do it in codelab, but in his example they created class FlowStepFragmentArgs, and it is voluminous

data class FlowStepFragmentArgs(val flowStepNumber: Int = 2) : NavArgs {
    fun toBundle(): Bundle {
        val result = Bundle()
        result.putInt("flowStepNumber", this.flowStepNumber)
        return result
    }

    companion object {
        @JvmStatic
        fun fromBundle(bundle: Bundle): FlowStepFragmentArgs {
            bundle.setClassLoader(FlowStepFragmentArgs::class.java.classLoader)
            val __flowStepNumber : Int
            if (bundle.containsKey("flowStepNumber")) {
                __flowStepNumber = bundle.getInt("flowStepNumber")
            } else {
                __flowStepNumber = 2
            }
            return FlowStepFragmentArgs(__flowStepNumber)
        }
    }
}

Q: How can I transfer data beautifully in my case

Upvotes: 0

Views: 90

Answers (2)

Alok Mishra
Alok Mishra

Reputation: 2034

Using Navigation Architecture you can do it as :- Let you have declared fragments in your navigation.xml file as :-

 <fragment
    android:id="@+id/fragment_a"
    android:name="com.example.FragmentA">
    <action android:id="@+id/action_item_click"
        app:destination="@id/fragment_b" />
</fragment>

<fragment
    android:id="@+id/fragment_b"
    android:name="com.example.fragmentB">
    <argument android:name="id" app:argType="string" android:defaultValue="sample data" />
</fragment>

Note :-

  1. A class is created for each destination where an action originates. The name of this class is the name of the originating destination, appended with the word "Directions".
  2. This class has a method for each action defined in the originating destination.

So for FragmentA class it will be generated as FragmentADirections eg. -

override fun onListItemClick(itemIndex: Int, itemCode: String) {
    findNavController().navigate(FragmentADirections.actionItemClick("Pass YOUR_STRING"))
}

Note :-

  1. A class is created for the receiving destination. The name of this class is the name of the destination, appended with the word "Args".

And for FragmentB class it will be generated as you can get data as FragmentBArgs eg:-

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    // do what you want with this id
    arguments?.let {bundle->
       val id = FragmentBArgs.fromBundle(bundle).id
    }
              // OR you can do also as
    // val id = arguments?.getString("id").orEmpty()
}

For more details please take reference of https://developer.android.com/guide/navigation/navigation-pass-data

Upvotes: 2

Dmitrii Leonov
Dmitrii Leonov

Reputation: 1389

As far as I know there are really only 2 options to pass data using Jetpack Navigation.

1) Using Bundle. Here I find budnleOf(x to y) function really handy

    val targetGuid = adapter.getItem(itemIndex) as Target).guid)
    val bundle = bundleOf(KEY_TARGET_GUID, targetGuid)
    findNavController().navigate(R.id.target_edit, bundle)

2) By defining arguments of your destination inside your navigation graph. Which will generate code. Assuming you R.id.target_edit is a fragment:

<fragment
    android:id="@+id/target_edit"
    android:name="com.example.TargetEditFragment"
    tools:layout="@layout/fragment_target_edit">
    <argument
        android:name="targetGuid"
        android:defaultValue="@null"
        app:argType="com.example.Target"
        app:nullable="true"/>
 </fragment>

Then in your TargetEditFragment

override fun onCreate(savedInstanceState: Bundle?) {
  val targetGuid =
    arguments?.let { TargetEditFragmentArgs.fromBundle(it).targetGuid }
}

Upvotes: 0

Related Questions