Jetpack Navigation Multiple backstack Bottom Menu, one graph, wrong selected item behavior

36 Views Asked by At

I want to implement multiple backstacks for my project. For testing purposes, I created a default bottom navigation project and just added one nested fragment to test how it works. And I found in some cases the bottom menu doesn't work as I expected.

Example: I have 3 menu items in the bottom menu: Home, Dashboard, and Notification. I created an additional Deep Fragment, Then I started my app, home fragment opened, I go to the Deep Fragment, then went to the notification tab, and also went to the Deep Fragment, in this case, multiple back stacks works as expected it saves the state of fragments, but when I switch back to the Home fragment, the home icon in the bottom menu doesn't highlight. In this case my navigation.xml

 <?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/mobile_navigation"
    app:startDestination="@+id/navigation_home">

    <fragment
        android:id="@+id/navigation_home"
        android:label="@string/title_home"
        android:name="com.test.myapplication.ui.home.HomeFragment"
        tools:layout="@layout/fragment_home" />

    <fragment
        android:id="@+id/navigation_dashboard"
        android:label="@string/title_dashboard"
        android:name="com.test.myapplication.ui.dashboard.DashboardFragment"
        tools:layout="@layout/fragment_dashboard" />

    <fragment
        android:id="@+id/navigation_notifications"
        android:label="@string/title_notifications"
        android:name="com.test.myapplication.ui.notifications.NotificationsFragment"
        tools:layout="@layout/fragment_notifications" />


    <fragment
        android:id="@+id/DeepFragment"
        android:label="@string/title_notifications"
        android:name="com.test.myapplication.ui.notifications.NotificationsFragment2"
        tools:layout="@layout/fragment_notifications" />


</navigation>

I did some research and maybe I got it wrong but do I need to include a graph for each tab, and each fragment there. In this way, the bottom menu works properly. But I won't duplicate fragments in all navigation files and I can't include some general graph. I can't navigate from the one included graph to the other, in my app I have a lot of shared screens. I can't include some general graph with shared fragments. How do you guys handle all this?

1

There are 1 best solutions below

0
On

Option1:
You can use android:menuCategory="secondary" in bottom_nav_menu. In this scenario back stack is not supported, fragments back stacks are lost.

Option2:
Using nested graphs. This solution also helps manage complex navigation graphs. In this case you can use like that:

mobile_navigation.xml

<?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"
        android:id="@+id/mobile_navigation"
        app:startDestination="@+id/navigation_home">
    
        <include app:graph="@navigation/navigation_dashboard" />
        <include app:graph="@navigation/navigation_notifications" />
        <include app:graph="@navigation/navigation_home" />
    </navigation>

navigation_home.xml

 <?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/navigation_home"
        app:startDestination="@id/homeFragment">
    
        <fragment
            android:id="@+id/homeFragment"
            android:name="com.example.myapplication.ui.home.HomeFragment"
            android:label="fragment_home"
            tools:layout="@layout/fragment_home" />
    </navigation>

navigation_dashboard.xml

<?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/navigation_dashboard"
        app:startDestination="@id/dashboardFragment">
    
        <fragment
            android:id="@+id/dashboardFragment"
            android:name="com.example.myapplication.ui.dashboard.DashboardFragment"
            android:label="fragment_dashboard"
            tools:layout="@layout/fragment_dashboard" >
            <action
                android:id="@+id/action_dashboardFragment_to_navigation_detail"
                app:destination="@id/navigation_detail" />
        </fragment>
        <include app:graph="@navigation/navigation_detail" />
    </navigation>

navigation_notifications.xml

<?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/navigation_notifications"
        app:startDestination="@id/notificationsFragment">
    
        <fragment
            android:id="@+id/notificationsFragment"
            android:name="com.example.myapplication.ui.notifications.NotificationsFragment"
            android:label="fragment_notifications"
            tools:layout="@layout/fragment_notifications" >
            <action
                android:id="@+id/action_notificationsFragment_to_navigation_detail"
                app:destination="@id/navigation_detail" />
        </fragment>
        <include app:graph="@navigation/navigation_detail" />
    </navigation>

navigation_detail.xml

<?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"
        android:id="@+id/navigation_detail"
        app:startDestination="@id/notificationsFragment2">
    
        <fragment
            android:id="@+id/notificationsFragment2"
            android:name="com.example.myapplication.ui.deep.NotificationsFragment2"
            android:label="NotificationsFragment2" />
    </navigation>