Search code examples
androidkotlinandroid-jetpackandroid-jetpack-navigation

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


Solution

  • 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