We use menus to show additional app functions without taking up too much screen space.
There are 3 types of menus:
- Options menus – these are mainly an activity’s menu items. Usually these options impact the app, an example being the Settings option
- Context menus – these are menus that appear in a floating window when the user clicks on a particular element. These options affect that element
- Popup menus – this is also a floating window. It displays a list of items anchored to the view that the user clicked
Import the support classes
The Action Bar and popup menus have only been available since Android 3.0.
We’re using the support library so we’re able to use these on devices using earlier versions of Android.
This tutorial applies to apps running on Android 2.1 (API Level 7) and later.
Use the support library’s PopupMenu class to provide popup menus in apps prior to Android 3.0 (API Level 11)
If used in apps running on Android 3.0 and higher, they will also use this class and not switch to the framework’s newer class.
Create your activity by extending the support library’s ActionBarActivity class to add an Action Bar to activities running on Android 2.1 (API Level 7) and higher
The Tutorial App: a summary
Our app displays 2 images. Long-clicking the top one displays a popup menu. Long-clicking the bottom one displays a context menu. Selecting either of the context menu options changes the size of the image.
Clicking the menu button of older devices displays the options menu at the bottom of the screen. Pressing the overflow menu button on newer devices displays the options menu at the top of the screen.
One options menu item is set as an action item and its icon displays on the Action Bar. Pressing this displays a submenu. Selecting Sub-menu item one from the options, adds Item Four to the options menu. Selecting Item Four from the options menu removes it as an item from the options menu.
Flag your important menu items as action items and they’ll appear on the Action Bar if there’s room. The rest will appear in the overflow menu.
You can include an icon for your action items to display on the Action Bar. The icon won’t display in the overflow menu.
You can include submenus, check boxes and radio buttons in the overflow menu but not on the Action Bar.
The options menu appears at the top of the screen on a Jelly Bean device and at the bottom of the screen on a Froyo device
Creating the options menu dynamically in code
You can create your menus dynamically in code, like this:
The onCreateOptionsMenu is called once to create the initial menu
Note the following:
- Always call through to the super class as it may add extra system menu options
- getMenuInflater().inflate – you don’t need to inflate a menu resource file. You can create your whole menu in code without one. We’re using a menu resource file and adding an item in code. We inflate the menu resource file, main.xml . inflate() has two parameters:
- the resource file that we want to inflate
- the Menu object that we want to inflate the resource into
- title – the text that will display in the menu
- groupId – this is the ID of a group of items that this item can belong to. You can group menu items together so that you can make changes to the group; for example, you could set all the items in a group to invisible. Our item does not belong to a group so we pass the NONE constant
- itemId – this is the unique ID of the item. We use the constant for Menu.FIRST which is 1. You can use Menu.FIRST + 1 for the next item and so on
- order – this is the order of the item in the list. We use 103 here so that this item follows item two (defined in the main.xml file) which has an order of 102. You can use Menu.NONE if the order of the items is not important
- add – we add the item to the menu object, passing the relevant parameters
- return true so that the menu can be displayed
You can also create the menu in xml.
Creating the options menu in xml
It’s better to define the menu in xml and then inflate it in your activity or fragment when needed.
Here’s how we defined the context menu in xml. It’s saved as the my_context_menu.xml file in the res/menu folder:
Our context menu has two items. We’ve only included the id and title attributes. There are other attributes that you can include
Defining your menu in xml:
- Makes it easy to visualize the structure of your menu
- Separates your menu content from behavioural code
- Allows you to create alternative menu structures for different screen sizes and platforms
Specifying the action bar actions
You can display important menu items on the Action Bar as text, an icon or both. To do so, you need to flag them as action items, either in code or in the xml resource file.
The action item icon displayed on the Action Bar
We’ve set our Item One as an action item in our menu resource file.
We’re using the support library so the showAsAction attribute is not available from the android:namespace where we would normally use it like this:
Instead, we need to define our own namespace which we use to prefix the showAsAction attribute.
The namespace should be based on your app name but it could be anything. It’s only accessible within the scope of the file in which you declare it.
This is how we did it:
Note the my_menu_tutorial namespace which we declare at the top and then use it to prefix the showAsAction attribute in the <item> element
You can also use flags to set an item as an action item in code. Use the setShowAsAction() method and pass it the appropriate flag.
We’ve included a submenu in our code above. We simply include a <menu> element within the <item> element. You can’t have nested submenus.
Our submenu displays in a floating window
Handling Option menu selections
onOptionsItemSelected is called whenever an options menu item is selected.
Here’s the code:
onOptionsItemSelected is called whenever an options item is selected. We use a switch statement to execute code for matching selected items
Note the following:
- The selected item is passed as a parameter to the method
- getTitle – there are a number of get<type> methods that you can use to get information about the selected item. We’re interested in the title of the selected item which we display in a Toast message
- getItemId – we get the ID of the selected item which we then use in the switch statement
- We use a switch statement to filter the matching items. We’re looking for two items in particular:
- the first item in the submenu – if it matches then we set isItemOneSelected to true. We’ll use this boolean later in onPrepareOptionsMenu
- the second is Item Four which we added in onPrepareOptionsMenu. If it matches then we set isRemoveItem to true. We’ll use this boolean later in onPrepareOptionsMenu
- supportInvalidateOptionsMenu – in both case statements we call supportInvalidateOptionsMenu. This is the support library’s version of invalidateOptionsMenu. It invalidates the activity's option menu ensuring a call to onCreateOptionsMenu and onPrepareOptionsMenu which updates the menu
- return true if we handled the selection else false
Updating the Options menu items dynamically
If you want to update a menu while your app is running, then override onPrepareOptionsMenu which is triggered just before the menu is shown.
You can dynamically add and remove items, as well as enable/disable, set the visibility and modify the text of menu items.
You’ll need to call supportInvalidateOptionsMenu if you want onPrepareOptionsMenu to be executed to make the changes to the menu. Have a look how we did it in onOptionsItemSelected.
onPrepareOptionsMenu is called just before the menu is shown. Use it to make changes to the menu. Remember to call supportInvalidateOptionsMenu() to ensure that it is called
Note the following:
- The first if statement – we check if the first submenu item was selected and that we haven’t previously added another item. If this is the case then we add Item Four to the menu and set isItemAdded to true
- The second if statement – we check if we need to remove Item Four. If this is the case then we remove it. Then we set the booleans: isRemoveItem, isItemOneSelected, and isItemAdded to false
- Return true so that the menu can be displayed. The updated menu is then displayed
If you haven't already done so, have a look at Using the contextual action mode for contextual menus in your apps: A tutorial.
Context menus display actions that affect the specific element to which they are attached.
The context menu appears in a floating window which closes when an item is selected.
A screenshot of our context menu
Creating the context menu
You can create the context menu dynamically in code or in xml like this:
We’ve created our context menu in xml and saved it as a menu resources file, my_context_menu.xml which is saved in the res/menu folder
Displaying the context menu
A context menu is assigned to a particular element. Ours is attached to an image view. We need to register our context menu so that it will be linked to the image view. Here’s how we did it:
Register the context menu so that it will show when our image view is clicked
The context menu will show when the image is clicked. This will trigger onCreateContextMenu where the menu is prepared before it is shown.
onCreateContextMenu is called just before the context menu is shown
We use onCreateContextMenu to set the header to display in the context menu window. We also add an icon here.
Handling the context menu selections
onContextItemSelected is called whenever a context menu item is selected. Here’s the code:
We change the image depending on which context menu item was selected
Note the following:
- We use getItemId() to get the ID of the selected item. This is used in the switch statement
- We use a switch statement to filter the selected item. The code in the matching case statement is then executed, and either a big or small image is displayed
Popup menus appear in a window attached to the view that was clicked. They’re an alternative to context menus.
Our popup menu is attached to the top image view
You create them the same as you would options menus.
Creating the menu
We’ve created ours in xml and saved it as a menu resource file, my_popup_menu which is saved in the res/menu folder. Here’s the code:
Define the popup menu in xml
Displaying the popup menu
Our popup menu is attached to an image view. Long-clicking the image displays the popup menu.
Here’s the code:
Long-clicking the image displays the popup menu. It’s dismissed when an item is selected
Note the following:
- Our popup menu is attached to the imageViewPopup image view
- We have a long-click listener attached to the image. It’s onLongClick() method is executed when the image is clicked
- doPopup – our method that creates and shows the popup menu. It’s called when the user long-clicks the image
Here’s the code for the doPopup() method:
Our doPopup() method creates and displays the popup menu
Note the following:
- we create a PopupMenu object. We’re using the support library’s version of the PopupMenu class. This version will be used by the app no matter which Android version is installed on the device
- setOnMenuItemClickListener – this listener will be notified when the user selects an item
- onMenuItemClick – this method’s code is executed when the popup menu item is selected. We use a switch statement to filter the selected item. The matching case statement is executed and in each case displays an appropriate Toast message
- return true to indicate that we have handled the click else false
- inflate – we inflate the popup menu resource file into the popup menu object
- show – shows the popup menu
I hope that you have found this tutorial helpful.
Check out our tutorial, Adding menus programmatically, where we show you how to add menus in code, without using XML.
You may also be interested in this eBook, Android fragments, Action Bar, Menus, Notifications and Tabs.
This tutorial was created using Android Studio. You can download the project files here
Are you using Eclipse or another IDE? Here's how you can use this project's Android Studio files.