Search code examples
androidandroid-fragmentsandroid-architecture-componentsandroid-jetpack-navigation

Pressing back always return to start destination using jetpack navigation


So, I have BottomNavigationView tied with Jetpack Navigation. Let say I have 4 bottom navigation menus, Fragment A, B, C, and D and A as the start destination. From Fragment A, I go to Fragment B, and then to Fragment C. Then, I pressed the hardware back button. I expected it to return to fragment B, instead, it return to Fragment A (which is the start destination).

This is the code:

val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment_activity_main) as NavHostFragment
navController = navHostFragment.navController

binding.navView.setupWithNavController(navController)

How can I change the behavior?

Thanks~

EDIT: I followed answers from Zain and the behavior is already as expected. But, there is another problem. Let say I have another fragment A1 which is not a part of BottomNavView fragment. I can navigate from fragment A to fragment A1. Below is the nav graph:

<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_a">

    <fragment
        android:id="@+id/navigation_a"
        android:name="com.example.FragmentA"
        android:label=""
        tools:layout="@layout/fragment_a">
        <action
            android:id="@+id/action_navigation_a_to_navigation_a1"
            app:destination="@id/navigation_a1"
            app:launchSingleTop="true" />
    </fragment>
    <fragment
        android:id="@+id/navigation_a1"
        android:name="com.example.FragmentA1"
        android:label=""
        tools:layout="@layout/fragment_a1" />
    <fragment
        android:id="@+id/navigation_b"
        android:name="com.example.FragmentB"
        android:label=""
        tools:layout="@layout/fragment_b" />
    <fragment
        android:id="@+id/navigation_c"
        android:name="com.example.FragmentC"
        android:label=""
        tools:layout="@layout/fragment_c" />
    <fragment
        android:id="@+id/navigation_d"
        android:name="com.example.FragmentD"
        android:label=""
        tools:layout="@layout/fragment_d" />
</navigation>

If I navigate from Fragment A to fragment A1, then navigate to fragment B and then press back, it shows the correct fragment which is A1, but the BottomNavigation still shows fragment B as the active fragment instead of fragment A.


Solution

  • A as the start destination. From Fragment A, I go to Fragment B, and then to Fragment C. Then, I pressed the hardware back button. I expected it to return to fragment B, instead, it return to Fragment A (which is the start destination).

    This is the default behavior of navigation architecture components; all the BottomNavView fragments are pop up from the back stack once you transacted to another fragment except for the start destination fragment.

    In order to change this, the documentation says:

    By default, the back stack will be popped back to the navigation graph's start destination. Menu items that have android:menuCategory="secondary" will not pop the back stack.

    So, you need to add android:menuCategory="secondary" in all of the menu items other than the start destination item. In your case, they are fragment b, c, and d items:

    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item
            android:id="@+id/fragment_a"
            android:icon="...."
            android:title="A" />
    
        <item
            android:id="@+id/fragment_b"
            android:menuCategory="secondary"
            android:icon="...."
            android:title="B" />
    
        <item
            android:id="@+id/fragment_c"
            android:menuCategory="secondary"
            android:icon="...."
            android:title="C" />
            
        <item
            android:id="@+id/fragment_d"
            android:menuCategory="secondary"
            android:icon="...."
            android:title="D" />
            
    </menu>