I created an application with a bottom navigation bar and added four different nav graphs using google's advanced navigation example
After that I added a fifth graph called settings that had the settings fragment along with a global action
I added an include to that graph on each of the first four graphs
when I do something like findNavController(R.id.container).navigate(SettingsDirections.showSettings())
the app crashes because it cannot find the destination or the action
but when I copy the fragment
and the global action
inside each of those graphs and call the above (with that graph's directions) it works
am I missing something? doesn't include actually copy everything from the other graph the original?
You can use a global action to create a common action that multiple destinations can use. For example, you might want buttons in different destinations to navigate to the same main app screen.
A navigation graph is a resource file that contains all of your app's destinations along with the logical connections, or actions, that users can take to navigate from one destination to another. You can manage your app's navigation graph using the Navigation Editor in Android Studio.
NavController manages app navigation within a NavHost . Apps will generally obtain a controller directly from a host, or by using one of the utility methods on the Navigation class rather than create a controller directly. Navigation flows and destinations are determined by the navigation graph owned by the controller.
Figure 1. A global action that leads to a nested graph. From the Graph Editor, click on a destination to highlight it. Right-click on the destination to display the context menu. Select Add Action > Global. An arrow ( ) appears to the left of the destination. Click the Text tab to navigate to the XML text view.
By default Navigation Component doesn’t have support to multiple navigation graphs, then using a workaround used by Android’s team in their projects we make use of a Navigation Extension and within the Main Activity tie all the wires. To highlight: with this navigation extension the fragment state is saved as well which is very important.
We explicitly want the navHostLoggedInView for the bottom navigation bar. When you have multiple navigation graphs, and you want the ActionBar to update accordingly, you would need to remember to call this each time you "switch" between navigation graphs. Finally, the ActionBar's Up button should be explicitly handled.
To use a global action in your code, pass the resource ID of the global action to the navigate () method for each UI element, as shown in the following example: For information on using Safe Args with global actions, see Pass data between destinations. To learn more about navigation, consult the following additional resources.
It seems that the include tag does not actually include all of the nav graph including the global actions
so in case someone wants to do something similar here is how I did it
first I updated the settings navigation to include a dummy action to show settings like so:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/settings"
app:startDestination="@+id/settings_dest">
<include app:graph="@navigation/questions" />
<!--this is just so safeargs will create a SettingsNavigation.showSettings it is never actually used-->
<action
android:id="@+id/show_settings"
app:destination="@id/settings_dest" />
<fragment
android:id="@+id/settings_dest"
android:name="com.example.app.ui.fragments.SettingsFragment"
android:label="@string/settings"
tools:layout="@layout/fragment_settings" >
<argument
app:argType="com.example.app.ui.model.SettingsProfile"
android:name="profile"
app:nullable="false"/>
</fragment>
</navigation>
and then on every nav graph that I wanted to use the show_settings action I would do by including this:
<include app:graph="@navigation/settings" />
<action
android:id="@+id/show_settings"
app:destination="@id/settings"
app:enterAnim="@anim/fade_in"
app:exitAnim="@anim/fade_out"
app:popEnterAnim="@anim/fade_in"
app:popExitAnim="@anim/fade_out" />
so now when I want to use directions to go to settings I do it like this
findNavController().navigate(SettingsDirections.showSettings(profile))
this will use the directions created in my settings.xml
to execute the action in my current nav controller
it is important by the way the id of the action in the included file and the id of the action of the file including it to be the same
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