Francis
Francis

Reputation: 7104

Pass safe-args when navigate to fragment

It's quite easy to pass safe-args when using navigation through an action (with directions class). But how to pass safe-args in case of using navigation to fragment directly?

navController?.navigate(R.id.detailFragment)

nav_graph:

<fragment
    android:id="@+id/detailFragment"
    android:name="com.example.ui.main.detail.DetailFragment"
    android:label=" "
    tools:layout="@layout/detail_fragment" >
    <argument
        android:name="templateCode"
        app:argType="string" />
    <action
        android:id="@+id/action_start_guide"
        app:destination="@id/fillInfoFragment" />
</fragment>

Upvotes: 8

Views: 14309

Answers (2)

Sergei Bubenshchikov
Sergei Bubenshchikov

Reputation: 5371

It's a good idea to use type-safe way because it take you compile time safety and some convenience.

This library will build argument's class MyDestinationArgs. You can use it to build Bundle and pass result to destination this way:

val args = DetailFragmentArgs.Builder("template_code").build().toBundle()
navController?.navigate(R.id.confirmationAction, args) 

On receiver side, you can retrieve data also using arguments class:

val templateCode = SecondFragmentArgs.fromBundle(arguments).templateCode

If we can't use safeargs library by some reasons,

we can pass data also inside Bundle. Suppose you have added

const val ARG_TEMPLATE_CODE = "templateCode"

constant in companion object of DetailFragment (static final field in Java)

Now you can pass data this way:

val args = Bundle()
args.putString(DetailFragment.ARG_TEMPLATE_CODE, "some_code")
navController?.navigate(R.id.confirmationAction, args)

And receiver fragment can obtain data from arguments:

arguments?.getString(ARG_TEMPLATE_CODE)

Or, if target destination is Activity, you can get data from intent extras (ARG_TEMPLATE_CODE constant now from destination activity):

intent?.extras?.getString(ARG_TEMPLATE_CODE)
  

Read more in documentation here and here.

Upvotes: 19

Francis
Francis

Reputation: 7104

The safe way is to define global action in case of need to navigate to fragment "directly"

<fragment
    android:id="@+id/detailFragment"
    android:name="com.example.ui.main.detail.DetailFragment"
    android:label=" "
    tools:layout="@layout/detail_fragment" >
    <argument
        android:name="templateCode"
        app:argType="string" />
    <action
        android:id="@+id/action_start_guide"
        app:destination="@id/fillInfoFragment" />
</fragment>

<action
    android:id="@+id/action_detail_fragment"
    app:destination="@id/fillInfoFragment" />

then

findNavController().navigate(NavGraphDirection.actionDetailFragment(templateCode))

Upvotes: 1

Related Questions