Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using global actions with multiple graphs in jetpack navigation

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?

like image 403
Cruces Avatar asked Jun 26 '20 08:06

Cruces


People also ask

What is global action in navigation component?

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.

What is the resource type of navigation graph?

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.

What is NavController in Android?

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.

How do I create a global action that leads to a graph?

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.

How to create multiple navigation graphs in Android with navigation component?

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.

How to handle multiple navigation graphs in Actionbar?

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.

How do I use a global action in my code?

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.


1 Answers

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

like image 122
Cruces Avatar answered Oct 24 '22 11:10

Cruces