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.
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.
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"
.
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
}
}
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")
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 argType
s:
<argument
android:name="data"
app:argType="string[]" />