Reputation: 193
I'm building an android application with 3 menus using bottom navigation. I created new project in Android Studio using Bottom Navigation Activity.
I renamed the fragment to:
InfoFragment.kt
DetectFragment.kt
AboutFragment.kt
Renamed the layout in src/main/res/layout
to:
fragment_info.xml
fragment_detect.xml
fragment_about.xml
Renamed the menu in src/main/res/menu
to:
navigation_info
navigation_detect
navigation_about
In the fragment_about.xml
I added a Button buttonGoToFAQ
to navigate to fragment_faq
like this with this code in AboutFragment.kt
buttonGoToFAQ.setOnClickListener {
val action = AboutFragmentDirections.actionFAQ()
Navigation.findNavController(it).navigate(action)
}
After I clicked BottomNavigationView menu either navigation_info
or navigation_detect
, and go back by clicking navigation_about
menu, the selected menu on the BottomNavigationView is not changed.
See this picture.
What I want is the menu navigation_about
should have been selected instead of other menu.
I already tried overriding fun onStart()
and fun onResume()
in FAQFragment.kt
but to no avail.
nav_view
is my BottomNavigationView.
override fun onStart() {
super.onStart()
(requireActivity().findViewById<View>(R.id.nav_view) as BottomNavigationView).selectedItemId =
R.id.navigation_about
}
I also recognize that all the BottomNavigationView menu's id have the same ids as the id in the src/main/res/navigation
xml file
Upvotes: 9
Views: 3812
Reputation: 31
As also suggested by @Francis, this is what you're looking for. I saw your answer but that is not the optimal solution, that is just a workaround that you have found.
bottomNavigationView.setOnItemSelectedListener {
item - >
// In order to get the expected behavior, you have to call default Navigation method manually
NavigationUI.onNavDestinationSelected(item, navController)
return @setOnItemSelectedListener true
}
Upvotes: 3
Reputation: 187
This is the intended behavior, according to this link to Google's Issue tracker - https://issuetracker.google.com/issues/210687967?pli=1
In a nutshell, Google wants us to use Nested Navigation Graphs to link FaqFragment
and AboutFragment
.
This will result in menu navigation_about
to be selected whenever either of the fragments are opened.
nav_graph.xml
, add a nested graph -<?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/nav_graph"
app:startDestination="@id/infoFragment">
<fragment
android:id="@+id/infoFragment"
android:name="......"
android:label="..." >
....
</fragment>
<fragment
android:id="@+id/detectFragment"
android:name="......"
android:label="...." >
....
</fragment>
<navigation android:id="@+id/toAboutNav"
app:startDestination="@id/aboutFragment">
<fragment
android:id="@+id/aboutFragment"
android:name="....."
android:label="....." >
.......
</fragment>
<fragment
android:id="@+id/faqFragment"
android:name="...."
android:label="...">
....
</fragment>
</navigation>
</navigation>
bottom_nav_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@id/infoFragment"
android:icon="...."
android:title="...." />
<item
android:id="@id/detectFragment"
android:icon="...."
android:title="...." />
<item
android:id="@id/toAboutNav"
android:icon="...."
android:title="...." />
</menu>
Upvotes: 8
Reputation: 7104
You can navigate manually and always return true
to the OnItemSelectedListener
to achieve menu item selection.
binding.bottomNavigation.setOnItemSelectedListener { item ->
NavigationUI.onNavDestinationSelected(item, navController)
true
}
Upvotes: 6
Reputation: 193
After some days, I finally get the answer by myself. First, I need to get the BottomNavigationView
from MainActivity
, after that, you can just change the menu item value from another fragment.
In MainActivity.kt
:
companion object {
lateinit var binding: ActivityMainBinding
{
On Fragment,
Define BottomNavigationView
and set the desired index in onResume()
:
class FAQFragment : Fragment() {
private val navView: BottomNavigationView = MainActivity.binding.navView
...
override fun onResume() {
super.onResume()
navView.menu.getItem(2).isChecked = true
}
}
Upvotes: 6