43

I am rewriting my simple UI app to use Navigation architecture component, I need to pass a Pojo that implements Parcelable, have not seen any doc on how to do that.

Any help would be appreciated.

Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
Jerry Okafor
  • 3,710
  • 3
  • 17
  • 26

4 Answers4

50

Since safe-args-gradle-plugin:1.0.0-alpha03 you can use Parcelable objects by using their fully qualified class name:

<argument
    android:name="item"
    app:argType="com.example.app.model.Item"/>

Parcelable arguments are now supported, using a fully qualified class name for app:type. The only default value supported is "@null" (https://issuetracker.google.com/issues/79563966)

Source: https://developer.android.com/jetpack/docs/release-notes


To support nullability one has to use android:defaultValue="@null" with app:nullable="true".

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
mbo
  • 4,611
  • 2
  • 34
  • 54
23

I know the answer is already there but this may help someone. Code snippet

In build.gradle add this dependancy

ext{
     ...
     navigation_version = '1.0.0-alpha11'
}
dependencies {
     ...
     classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:$navigation_version"
}

In app/build.gradle

apply plugin: 'androidx.navigation.safeargs'
...

In Navigation graph


 <fragment
            android:id="@+id/source_fragment_id"
            android:name="app.test.SourceFragment"
            android:label="@string/source_fragment_label"
            tools:layout="@layout/source_fragment_layout">

         <action
                android:id="@+id/action_source_fragment_to_destination_fragment"
                app:destination="@id/destination_fragment_id"
                ...
                />


</fragment>

<fragment
            android:id="@+id/destination_fragment_id"
            android:name="app.test.DestinationFragment"
            android:label="@string/destination_fragment_label"
            tools:layout="@layout/destination_fragment_layout">

        <argument
                android:name="variableName"
                app:argType="app.test.data.model.CustomModel" />

        ...

</fragment>

Note: CustomModel should be Parcelable or Serializable.

When navigating to this DestinationFragment from SourceFragment

val direction = SourceFragmentDirections.ActionSourceFragmentToDestinationFragment(customModel)
findNavController().navigate(direction)

Now retrieving the value from bundle in DestinationFragment

...
import app.test.DestinationFragmentArgs.fromBundle

class DestinationFragment : Fragment() {
   val variableName by lazy {
       fromBundle(arguments!!).variableName
   }

   ...
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        Log.e(DESTINATION_FRAGMENT_TAG,"onCreateView")

        //Can use CustomModel variable here i.e. variableName


   }

}
Suyash Chavan
  • 776
  • 9
  • 20
10

Right now you can't use safe args with types apart from integer, string, inferred and reference, there's an issue opened asking for other types.

What you can do now is to normally pass a bundle when using the navigate() method to navigate to a destination:

var bundle = bundleOf("amount" to amount)
view.findNavController().navigate(R.id.confirmationAction, bundle)

And you can use the usual getArguments (or just arguments in kotlin) to retrieve that:

val tv = view.findViewById(R.id.textViewAmount)
tv.text = arguments.getString("amount")
Levi Moreira
  • 11,917
  • 4
  • 32
  • 46
6

You can use boolean, reference, integer, long, string, enum, parcelable and even serializable. But forget about the last one ;-)

Better use the latest plugin version safe-args-gradle-plugin:1.0.0-alpha08 and specify the fully qualified classname:

<fragment
    ...>
    <argument
        android:name="data"
        app:argType="com.example.ParcelableData" />
</fragment>

from your

package com.example

data class ParcelableData(val content: String) : Parcelable { ... }

And you can send arrays of all the argTypes:

<argument
        android:name="data"
        app:argType="string[]" />
sbo3000
  • 176
  • 1
  • 7