I'm using Android Jetpack Navigation Component.
I have a nested nav graph with id, say R.id.nested_graph
The first Fragment
of the nested graph receives one parameter.
<navigation
android:id="@+id/nested_graph"
android:label="Nested Graph"
app:startDestination="@id/firstFragment">
<fragment
android:id="@+id/firstFragment"
android:name="...."
android:label="....">
<argument
android:name="item_id"
app:argType="integer" />
</fragment>
[...]
</navigation>
How can I pass the parameter to the nested graph using safe args?
At the moment, I need to pass the argument manually in the bundle, using the API that receives the id of the nested graph directly:
val args = Bundle()
args.putInt("item_id", itemId)
navController.navigate(R.id.nested_graph, args)
I'd like to use safe args, and do something like:
val directions = OrigininFragmentDirections.nestedGraph(itemId)
navController.navigate(directions)
But when trying that, I get the following error at build time:
Too many arguments for public final fun nestedGraph(): NavDirections defined
The issue is that the nav graph preprocessing is generating the factory method to create the NavDirections
object without the required parameter in the signature.
The declaration of the nested graph looks like this:
After some trial and error experimentation (I don't think it's officially documented by Google, or at least I could not find it), I've discovered that navigating to nested nav graphs passing arguments safely can be done:
You need to add the argument
XML object the first fragment expects in the root of the nested fragment itself.
In my case, the fragment with id firstFragment
, which is the first fragment in the nested graph receives:
<argument
android:name="item_id"
app:argType="integer" />
Hence, I need to add that argument to the nested graph:
<navigation
android:id="@+id/nested_graph"
android:label="Nested Graph"
app:startDestination="@id/firstFragment">
<argument
android:name="item_id"
app:argType="integer" />
<fragment
android:id="@+id/firstFragment"
android:name="...."
android:label="....">
<argument
android:name="item_id"
app:argType="integer" />
</fragment>
[...]
</navigation>
Now I can navigate to it with:
val directions = OrigininFragmentDirections.nestedGraph(itemId)
navController.navigate(directions)
Note that the navigation graph editor does not do it for you. This needs to be done manually in the XML code.
@GaRRaPeTa answer is almost correct, but if you navigate from main graph to nested graph by action using SafeArgs, you must also add an argument to the action:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/graph_main"
app:startDestination="@id/mainFragment">
<fragment
android:id="@+id/mainFragment"
android:name="com.example.MainFragment">
<action
android:id="@+id/toNestedGraph"
app:destination="@id/graph_nested">
<argument
android:name="arg_name"
app:argType="string" />
</action>
</fragment>
</navigation>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With