Search code examples
androidandroid-toolbarandroid-architecture-navigation

Toolbar menu onOptionsItemSelected does not work from fragment


I'm trying to change current fragment when user clicks the menu in toolbar using navigation components, however I can't get the menu to work from fragment at all! I'm using bottom navigation bar with 2 fragments and each fragment has different toolbar menu items, I'm not using navigation drawer. Here's a little snippet from HomeFragment.kt:

override​ ​fun​ ​onCreateView​(
    inflater​:​ ​LayoutInflater​, ​container​:​ ​ViewGroup?​,
    savedInstanceState​:​ ​Bundle?​
)​:​ ​View?​ {
    activity?.title ​=​ getString(​R​.string.title_home)
    setHasOptionsMenu(​true​)

    return​ inflater.inflate(​R​.layout.fragment_home, container, ​false​)
}

override​ ​fun​ ​onCreateOptionsMenu​(​menu​:​ ​Menu​, ​inflater​:​ ​MenuInflater​) {
    inflater.inflate(​R​.menu.toolbar_menu, menu)
    super​ .onCreateOptionsMenu(menu, inflater)
}

override​ ​fun​ ​onOptionsItemSelected​(​item​:​ ​MenuItem​)​:​ ​Boolean​ {
    when​ (item.itemId) {
         R​.id.toolbar_about ​-​>​ {
            activity?.findNavController(​R​.id.bottom_nav_host)?.navigate(​R​.id.toAboutFragment)
             Toast​.makeText(context, ​"​You clicked on About menu​"​, ​Toast​.​LENGTH_SHORT​).show()
        }
        else​ ​-​>​ ​super​.onOptionsItemSelected(item)
    }
    return​ ​true​
}

It doesn't even display the Toast that I specified. Could anyone help me? Thanks in advance!


Solution

  • I managed to fix this by calling onOptionsItemSelected directly from activity instead of fragment. So my final code looks like this:
    HomeFragment.kt:

    //We set menu from fragment
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { 
        inflater.inflate(R.menu.toolbar_menu, menu)
        super .onCreateOptionsMenu(menu, inflater) 
    }
    

    MainActivity.kt:

    override fun onOptionsItemSelected(item: MenuItem): Boolean { 
        val navHost = findNavController(R.id.bottom_nav_host) 
        when (item.itemId) { 
            android.R.id.home -> { 
                onBackPressed() 
                return true 
            }
            //This one is for our fragment toolbar menu
            R.id.toolbar_about -> { 
                navHost.navigate(R.id.toAboutFragment) 
                return true 
            }
        }
        return false
    }