Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reuse a fragment in different navigation graphs with safe args enabled?

I'm trying to reuse a fragment in different navigation graphs with safe args enabled. I noticed that if the actions are different I get a compilation error. This is because the xxxFragmentDirections autogenerated code will only generate one of the actions.

In nav_graph_1.xml:

<navigation 
  ...
  <fragment
    android:id="@+id/myFragment"
    android:name="com.example.android.MyFragment">
    <action
      android:id="@+id/next_action"
      app:destination="@+id/dest_one" />
  </fragment>
  ...

In nav_graph_2.xml:

<navigation 
  ...
  <fragment
    android:id="@+id/myFragment"
    android:name="com.example.android.MyFragment">
    <action
      android:id="@+id/other_action"
      app:destination="@+id/other_dest" />
  </fragment>
  ...

A simple use case: A bank app that has two flows: withdraw and deposit, therefore you could have two nav graphs. You could have an AmountFragment where you could just enter a number and this could be reused to either withdraw or deposit. However, depending on the flow, the actions/destinations could be different.

Then, how would it be possible to reuse this fragment?

like image 741
fernandospr Avatar asked Jan 12 '20 14:01

fernandospr


2 Answers

Use navigate() with bundle instead of actions in edge cases. Don’t call

findNavController().navigate(FragmentDirections.goToDetailFragment(id))

but instead use

findNavController().navigate(R.id.DetailFragment, bundleOf("id" to 5))

This way you don’t rely on the generated direction but can still use the Navigation and SafeArgs features of the DetailFragment.

https://code.allaboutapps.at/articles/android-jetpack-navigation-pitfalls/#reuse-fragments-in-multiple-navigation-graphs

like image 179
dabo248 Avatar answered Oct 04 '22 00:10

dabo248


This can be achieved by providing the same action ID in both the navigation graph.

In nav_graph_1.xml:

<navigation 
  ...
  <fragment
    android:id="@+id/myFragment"
    android:name="com.example.android.MyFragment">
    <action
      android:id="@+id/next_action"
      app:destination="@+id/dest_one" />
  </fragment>
  ...

In nav_graph_2.xml:

<navigation 
  ...
  <fragment
    android:id="@+id/myFragment"
    android:name="com.example.android.MyFragment">
    <action
      android:id="@+id/next_action"
      app:destination="@+id/other_dest" />
  </fragment>
  ...

In fragment, navigation can be performed like

NavHostFragment.findNavController(<myFragment>).navigate(R.id.next);

like image 20
Nilesh Tiwari Avatar answered Oct 04 '22 00:10

Nilesh Tiwari