Owen Lie
Owen Lie

Reputation: 193

BottomNavigationView's menu not selected after navigating to other fragment, switching to other menu, and switching back to initial menu

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:

Renamed the layout in src/main/res/layout to:

Renamed the menu in src/main/res/menu to:

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

Answers (4)

Wild Labs
Wild Labs

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

Smirky
Smirky

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.

  1. In your 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>
  1. Also, in your menu folder, make the following change in your 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

Francis
Francis

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

Owen Lie
Owen Lie

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

Related Questions