Computer scienceMobileAndroidUser InterfaceUI components

Menus: Options, Popup

8 minutes read

An app sometimes provides a list of available actions. Such lists are called menus and they may look different in different contexts.

Options menu in a Toolbar

In this topic, you'll learn how to create toolbar options menus, popup menus, and navigation menus.

There's a special type of XML resources for menus. To explore it, let's create a Menu Resource File app/src/main/res/menu/example.xml and try out different features.

<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/basic"
        android:title="Basic item" />

    <item
        android:id="@+id/checkbox"
        android:title="Checkable"
        android:checkable="true" />

    <item
        android:id="@+id/with_icon"
        android:icon="@android:drawable/ic_dialog_email"
        android:title="With icon"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/search_icon"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="always|collapseActionView"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        android:title="Search" />

</menu>

In the preview, you will see the following result:

Preview of an options menu from the snippet above

What do we have here?

  • A basic item. It has a title and can be clicked.
  • A checkable item. It has a check box, but setting the checked state when it gets clicked is your responsibility.
  • An item with an icon. showAsAction="ifRoom" means that we'd like to see it as an icon. But, if it exceeds the available space, it will be shown in the overflow menu as a text item.
  • A custom item. A search input field appears when clicked. Always shown as an action because having a search item in the overflow menu looks impractical. The collapseActionView flag makes the user interface more friendly when the search is expanded.

Menu items may also contain submenus. Despite being relatively easy, this technique is beyond the scope of this topic but can be learned from the official documentation.

Now it's time to show this menu on a screen. We will need a view serving as a menu host.

Toolbar

A Toolbar is a horizontal view, typically on top of the screen, providing quick actions, an app icon or back button, and a screen title. It is typically added to the layout manually.

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?actionBarSize"
    app:title="Learn menus" />

Make sure that the activity theme is set to something with .NoActionBar. Otherwise, a Toolbar will be created automatically and we will have less control over it.

Now we need to instruct the Activity that we have a Toolbar and inflate a menu. The up-to-date way to add menus is by implementing a MenuProvider.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_with_toolbar)

    val toolbar = findViewById<Toolbar>(R.id.toolbar)
    setSupportActionBar(toolbar)
    addMenuProvider(object : MenuProvider {
        override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
            menuInflater.inflate(R.menu.example, menu)
        }
        
        override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
            TODO()
        }
        
    })
}

With Fragments, do requireActivity().addMenuProvider(..., viewLifecycleOwner) in onCreateView() to add a menu that will be disposed of automatically when a Fragment disappears.

The onMenuItemSelected function is called when a menu item is clicked. Here we can check which item it was and perform any required actions. Returning true means that we've handled that action.

override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) {
    R.id.basic -> {
        Toast.makeText(this@MainActivity, menuItem.title, Toast.LENGTH_SHORT).show()
        true
    }
    R.id.checkbox -> {
        menuItem.isChecked = !menuItem.isChecked
        true
    }
    R.id.with_icon -> {
        Toast.makeText(this@MainActivity, menuItem.title, Toast.LENGTH_SHORT).show()
        true
    }
    R.id.search_icon -> {
        true // nothing to do here
    }
    else -> {
        false // none of my business
    }
}

SearchView requires special handling. To make the search useful, we need to handle some additional events.

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

    val search = menu.findItem(R.id.search_icon)
    val searchView = search.actionView as SearchView
    searchView.setOnQueryTextListener(object : OnQueryTextListener {

        override fun onQueryTextSubmit(query: String): Boolean {
            // The search was submitted by the user. Do something:
            Toast.makeText(this@MainActivity, query, Toast.LENGTH_SHORT).show()
            // …and collapse SearchView.
            search.collapseActionView()
            return true
        }

        override fun onQueryTextChange(newText: String): Boolean {
            return true
        }
    })
}

And here's the result:

Options menu in action

The same popup or drop-down can be created without a Toolbar and anchored to an arbitrary view. Just create a PopupMenu, inflate a menu, set a listener to handle clicks, and show it.

anyView.setOnClickListener { anyView ->
    PopupMenu(this@MainActivity, anyView).apply {
        inflate(R.menu.example)
        setForceShowIcon(true)
        setOnMenuItemClickListener { item ->
            Toast.makeText(it.context, item.title, Toast.LENGTH_SHORT).show()
            true
        }
        show()
    }
}

The setForceShowIcon function can be used to display icons in a list along with titles.

Popup menu

See also

  • Menu items can be gathered in groups, which is especially useful for checkable items.
  • A menu can be shown by long clicking on a view. This is called a contextual menu.
  • When an application provides batch actions for arbitrarily selected items (for example, a file manager or gallery can delete or move a lot of files in one action), opt for context action mode.

Conclusion

We can define a list of actions using the menu resource type. Menu items can be shown as Toolbar options or in a popup menu, and can have icons, be checkable, or provide a custom action view, such as SearchView.

11 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo