Bottom navigation bar malfunctions when navigating from a fragment
Asked Answered
K

3

7

I'm using the bottom navigation bar with the navigation component

To make the two components work together I called:

bottomNavigationView.setupWithNavController(navController)

Everything works as expected except when I navigate from inside a fragment instead of the bottom navigation bar

enter image description here

"View all" opens the same fragment as "Reports" from the bottom navigation bar

binding.viewAllScansTv.setOnClickListener {
    val action = MainFragmentDirections.actionMainFragmentToReportsFragment()
    navController.navigate(action)
}

After clicking on "View all", the fragment is opened, the "Reports" button gets selected, however, navigating back "Home" does not work anymore

How can I fix this weird behavior?

The nav graph:

<navigation app:startDestination="@id/mainFragment">
    <fragment
        android:id="@+id/mainFragment"
        android:name="com.package.name.ui.main.MainFragment"
        android:label="MainFragment"> 
        <action                android:id="@+id/action_mainFragment_to_reportsFragment"
            app:destination="@id/reportsFragment" />
    </fragment>
</navigation>

The bottom navigation menu:

<menu>
    <item
        android:id="@+id/mainFragment"
        android:title="Home"/>    
    <item
        android:id="@+id/reportsFragment"
        android:title="Reports"/>
    <item
        android:id="@+id/settingsFragment"
        android:title="My account"/>
</menu>
Keefer answered 18/3, 2022 at 10:16 Comment(5)
Please share your navGraphs; need to see the actionMainFragmentToReportsFragmentSoughtafter
I updated the question and added the nav graph and the bottom navigation menuKeefer
Not sure if you're using the right navController; can you use findNavController().navigate(action) insteadSoughtafter
tried it. nothing changesKeefer
Looks like an duplicate of this question.Freeloader
K
14

As @ianhanniballake mentioned in a comment, a similar question was posted here

What I ended up doing was replacing

val action = MainFragmentDirections.actionMainFragmentToReportsFragment()
navController.navigate(action)

with

val item = mainBottomNavigationView.menu.findItem(R.id.reportsFragment)
NavigationUI.onNavDestinationSelected(item, navController)

So basically I used the NavigationUI API to navigate so that it correctly tracks the back stack. The same NavigationUI API is being used by the BottomNavigationView internally

Keefer answered 25/3, 2022 at 8:57 Comment(0)
B
6

Your current answer is fine but if you need to pass arguments it wont work, So use this

In the Navigation XML add these lines to the action

app:launchSingleTop="true"
app:popUpTo="@+id/main_navigation"
app:popUpToInclusive="true"

And make sure app:popUpTo="@+id/main_navigation" has the same id as your navigation xml

So the final action should look like:

     <action
            android:id="@+id/action_cameraFragment_to_searchFragment"
            app:destination="@id/searchFragment"
            app:launchSingleTop="true"
            app:popUpTo="@+id/main_navigation"
            app:popUpToInclusive="true"/>

And Navigate normally using the action

val action = CameraFragmentDirections.actionCameraFragmentToSearchFragment()
findNavController().navigate(action)
Brassware answered 17/2, 2023 at 7:59 Comment(0)
G
1

Setting a click listener on any view should have the same effect as if the user taps the corresponding item in the bottom navigation. So you need to call setSelectedItemId() on the BottomNavigationView.

val mainBottomNav =
                activity?.findViewById<BottomNavigationView>(R.id.homeBottomNavigation)
            mainBottomNav?.selectedItemId = R.id.baseHomeFragment
Goran answered 4/11, 2022 at 4:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.