Hiding menu from toolbar on a specific fragment within the same activity

73 views Asked by At

I have an activity that hosts few fragments.

Once the first fragment comes to the activity, it inflates some menu (actually just one action button) on AppBar layout of the activity:

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

Once user is navigated to the second fragment within the same activity this action button should be hidden. I cannot achieve this (see my solutions below).

So, generally the question is:

How to hide menu from the activity AppBarLayout only for some fragments in the backstack?

NOTE: I don't need to hide the whole Toolbar (the title still should be shown, I want to hide only the action button!)

I tried different solutions that unfortunately don't work:

  1. Call setHasOptionsMenu(false) in the second fragment (tried both in onCreate and in onCreateView)
  2. Call activity.invalidateOptionsMenu() in different callbacks of the fragment and then try to hide the element of menu in onCreateOptionsMenu that should be called again after invalidate call. But I see it is not called even after invalidate call:
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    menu.forEach {
        it.isVisible = false
    }
}

Also tried to combine all these solution but it does not work - the button is still shown on the second fragment.

1

There are 1 answers

0
ltp On

onCreateOptionsMenu is already deprecated. You should use the MenuProvider api instead.

On your first fragment or the fragment where you want to show specific menu:

 private val menuProvider = object : MenuProvider {
            override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
                menuInflater.inflate(R.menu.menu_info, menu)
            }
    
            override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
                return when (menuItem.itemId) {
                    R.id.menu_info_menu1 -> {
                        //Do something
                        return true
                    }
                    R.id.menu_info_menu2 -> {
                        //Do something
                        return true
                    }
                    else -> false
                }
            }
        }

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        //show the menu
        requireActivity().addMenuProvider(menuProvider, this)

       //alternatively, you can also specify the specific lifecycle state 
       //when the the menu should show and hide like the following. 
        requireActivity().addMenuProvider(menuProvider, this, Lifecycle.State.RESUMED)
       //This will hide the menu when the fragment lifecycle state is below RESUMED. 
       //If not specified, it will be hidden when fragment is destroyed.

         
           ...
     
    }