Reputation: 1182
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
"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>
Upvotes: 7
Views: 3688
Reputation: 173
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
Upvotes: 1
Reputation: 145
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)
Upvotes: 6
Reputation: 1182
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
Upvotes: 14