3

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.

  • AFAIK; The fragment A1 should be in a separate navGraph than the fragments of the `BottomNavView` as it's not a part of the `BottomNavView` items.. The `BottomnNavView` fragments should be in a separate navGraph – Zain Nov 08 '21 at 16:31
  • I tried to separate it and it is still not solved and also I need to be in 1 graph. – Bernhard Josephus Nov 08 '21 at 16:40
  • This is expected behavior as your navigation now is `A (A highlighted) > A1 > B (B highlighted) > Back pressed > A1 (Still B highlighted)` as you didn't return from a `BottoomNavView` fragment to another; but you return from `BottoomNavView` to a fragment that is not in the `BottoomNavView`. You still didn't return to A to highlight it.. By the way this is another issue of your original question – Zain Nov 08 '21 at 19:03
  • But you can achieve that with some customization that I am working on; but I see that would be wider than the scope of this question; appreciate if you'd open another question for that. – Zain Nov 08 '21 at 19:21
  • @Zain this is the link to the new question https://stackoverflow.com/questions/69900915/bottomnavigationview-with-jetpack-navigation-not-correctly-showing-the-active-me – Bernhard Josephus Nov 09 '21 at 15:33

1 Answers1

5

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>
Zain
  • 37,492
  • 7
  • 60
  • 84
  • Sorry for the late response, I followed your answers and working as expected. But, I got another problem after that. I already edited my question explaining the problem. – Bernhard Josephus Nov 08 '21 at 12:07
  • @BernhardJosephus Do you implement `navView.setOnItemSelectedListener` or `navView.setOnNavigationItemSelectedListener` or something similar? – Zain Nov 08 '21 at 12:33
  • I don't. I forgot one thing, If I press back again (from fragment A1 to A), the active indicator then moved to fragment A. So, I need to press back twice to get it right. – Bernhard Josephus Nov 08 '21 at 12:42
  • Do you register `onBackPressedDispatcher` or handle back press programmatically in any of those fragments? – Zain Nov 08 '21 at 13:17
  • Nope. And I just realized, after set the `menuCategory`, every time I press the bottom nav menu, the stack state is gone. For example from fragment A to A1 and I press fragment A menu from bottom nav. It will navigate to fragment A so the stack is A -> A1 -> A. – Bernhard Josephus Nov 08 '21 at 13:26
  • Can you tell if the you handle the back press in the navGraph; like setting `popUpTo` or `PopUpToInclusive` properties; or handle any programmatically – Zain Nov 08 '21 at 14:24
  • Nope, I don't do any back press manually. The stack problem is solved, but the active fragment indicator still not solved yet. – Bernhard Josephus Nov 08 '21 at 15:21
  • `The stack problem is solved` I am confused on this as you told that you need to `press back twice to get it right`; so now if you hit back twice, this means that it is registered twice in the back stack. But if you press the back when you back to A1 while it's not highlighted; then it must go to A.. Can you clarify this – Zain Nov 08 '21 at 15:41
  • Sorry, the stack problem I mean is this one `...every time I press the bottom nav menu, the stack state is gone...`. The `press back twice to get it right` I'm guessing the navigator don't know that fragment A1 is belong to fragment A. – Bernhard Josephus Nov 08 '21 at 15:44
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/238993/discussion-between-zain-and-bernhard-josephus). – Zain Nov 08 '21 at 15:47
  • @BernhardJosephus have you found any solution around it? – tushar Dec 23 '21 at 04:00
  • Yes, I follow the above solution and make multiple navGraph containing the same fragments. So if you have 3 Bottom navigation menus, then you will have 3 navGraph (nav_a, nav_b, nav_c) + 1 main navGraph (nav_main). – Bernhard Josephus Dec 23 '21 at 04:41
  • I was having the same problem with a nav drawer and overflow items returning to the start destination. This fixed the issue, thank you! – Eric B. Aug 19 '22 at 02:05