Eriol
Eriol

Reputation: 21

How to add items to the menu bar using the new MenuProvider?

Very much a beginner question here. Since the old paradigm which used "setHasOptionsMenu(true)" in the fragments was recently deprecated in Android Studio, I have been trying to convert my app to the newest scheme as outlined in the documentation. All explanation about this I can find centers around the following code snippet from said documentation:

/**
  * Using the addMenuProvider() API directly in your Activity
  **/
class ExampleActivity : ComponentActivity(R.layout.activity_example) {

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

    // Add menu items without overriding methods in the Activity
   addMenuProvider(object : MenuProvider {
      override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
        // Add menu items here
        menuInflater.inflate(R.menu.example_menu, menu)
      }

      override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
        // Handle the menu selection
        return true
      }
    })
  }
}

/**
  * Using the addMenuProvider() API in a Fragment
  **/
class ExampleFragment : Fragment(R.layout.fragment_example) {

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    // The usage of an interface lets you inject your own implementation
    val menuHost: MenuHost = requireActivity()
  
    // Add menu items without using the Fragment Menu APIs
    // Note how we can tie the MenuProvider to the viewLifecycleOwner
    // and an optional Lifecycle.State (here, RESUMED) to indicate when
    // the menu should be visible
    menuHost.addMenuProvider(object : MenuProvider {
      override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
        // Add menu items here
        menuInflater.inflate(R.menu.example_menu, menu)
      }

      override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
        // Handle the menu selection
        return true
      }
    }, viewLifecycleOwner, Lifecycle.State.RESUMED)
  }

Now, I have tried to add this code to my main activity (extending AppCompatActivity() ) and associated fragments. Wherever it says "R.menu.example_menu" I have inserted my own menu layout files which contain basically only a single settings item most of the time.

However, while the code compiles without error, no item is actually added to the menu bar. What am I missing? Am I supposed to add the items manually where it says "add menu items here"? However, writing something such as "menu.add("Settings") doesn't seem to have an effect either.

Upvotes: 2

Views: 3375

Answers (3)

nitinkumarp
nitinkumarp

Reputation: 2160

Your implementation of Menu on Fragment is correct. You are missing a line in your Activity. You need to reference your Toolbar as ActionBar of your Activity to make menuHost to know where to add menuItems. Just add following line.

setSupportActionBar(binding.toolbar)

Upvotes: 0

Leonardo Sibela
Leonardo Sibela

Reputation: 2189

The easiest way is to make your fragment implement the MenuProvider interface:

class ExampleFragment : Fragment(R.layout.fragment_example), MenuProvider { ...

Then, on the onViewCreated method of your fragment, call the addMenuProvider method:

requireActivity().addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)

Then, you just have to implement the interface methods:

override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
    menuInflater.inflate(R.menu.example_menu, menu)
}

override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
    // Handle the menu selection
    return true
}

Upvotes: 3

User2207
User2207

Reputation: 40

Try the following in the Main Activity:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)

In other words, use AppCompatActivity() instead of ComponentActivity(), because AppCompatActivity() extends FragmentActivity which extends ComponentActivity().

  • make sure to use the androidX dependencies (import androidx.appcompat.app.AppCompatActivity)

Also, I am not sure what items you have, but it could be because of their constraints in the xml files. For example, if you have a TextView and you used tools:text="toolsText, you won't be able to see the text, since this is used only for Android Studio layout preview and it doesn't show text when you run the app.

I hope this can be helpful for you.

Upvotes: -2

Related Questions