diff --git a/docs/html/guide/topics/ui/menus.jd b/docs/html/guide/topics/ui/menus.jd index cf3c7decbcfdc..b4e467c273f2d 100644 --- a/docs/html/guide/topics/ui/menus.jd +++ b/docs/html/guide/topics/ui/menus.jd @@ -5,198 +5,324 @@ parent.link=index.html
-

Key classes

-
    -
  1. {@link android.view.Menu}
  2. -
  3. {@link android.view.ContextMenu}
  4. -
  5. {@link android.view.SubMenu}
  6. -

In this document

    -
  1. Options Menu
  2. -
  3. Context Menu
  4. -
  5. Submenu
  6. -
  7. Define Menus in XML
  8. -
  9. Menu Features +
  10. Defining Menus
  11. +
  12. Inflating a Menu Resource +
  13. Creating an Options Menu +
      +
    1. Changing the menu when it opens
    2. +
    +
  14. +
  15. Creating a Context Menu
  16. +
  17. Creating a Submenu
  18. +
  19. Other Menu Features
    1. Menu groups
    2. Checkable menu items
    3. Shortcut keys
    4. -
    5. Menu item intents
    6. +
    7. Intents for menu items
+ +

Key classes

+
    +
  1. {@link android.view.Menu}
  2. +
  3. {@link android.view.MenuItem}
  4. +
  5. {@link android.view.ContextMenu}
  6. +
  7. {@link android.view.SubMenu}
  8. +
+ +

See also

+
    +
  1. Menu Resource
  2. +
-

Menus are an important part of any application. They provide familiar interfaces -that reveal application functions and settings. Android offers an easy programming interface -for developers to provide standardized application menus for various situations.

+

Menus are an important part of an application that provide a familiar interface for the user +to access application functions and settings. Android offers an easy programming interface +for you to provide application menus in your application.

-

Android offers three fundamental types of application menus:

+

Android provides three types of application menus:

Options Menu
-
This is the primary set of menu items for an Activity. It is revealed by pressing - the device MENU key. Within the Options Menu are two groups of menu items: +
The primary menu for an Activity, which appears when the user presses + the device MENU key. Within the Options Menu are two groups:
Icon Menu
-
This is the collection of items initially visible at the bottom of the screen +
The menu items visible at the bottom of the screen at the press of the MENU key. It supports a maximum of six menu items. These are the only menu items that support icons and the only menu items that do not support checkboxes or radio buttons.
Expanded Menu
-
This is a vertical list of items exposed by the "More" menu item from the Icon Menu. - It exists only when the Icon Menu becomes over-loaded and is comprised of the sixth - Option Menu item and the rest.
+
The vertical list of menu items exposed by the "More" menu item in the Icon Menu. + When the Icon Menu is full, the expanded menu is comprised of the sixth + menu item and the rest.
Context Menu
-
This is a floating list of menu items that may appear when you perform a long-press on a View - (such as a list item).
+
A floating list of menu items that appears when the user performs a long-press on a View. +
Submenu
-
This is a floating list of menu items that is revealed by an item in the Options Menu - or a Context Menu. A Submenu item cannot support nested Submenus.
+
A floating list of menu items that the user opens by pressing a menu item in the Options +Menu or a context menu. A submenu item cannot support a nested submenu.
-

Options Menu

- -

The Options Menu is opened by pressing the device MENU key. -When opened, the Icon Menu is displayed, which holds the first six menu items. -If more than six items are added to the Options Menu, then those that can't fit -in the Icon Menu are revealed in the Expanded Menu, via the "More" menu item. The Expanded Menu -is automatically added when there are more than six items.

-

The Options Menu is where you should include basic application functions -and any necessary navigation items (e.g., to a home screen or application settings). -You can also add Submenus for organizing topics -and including extra menu functionality.

+

Defining Menus

-

When this menu is opened for the first time, -the Android system will call the Activity {@link android.app.Activity#onCreateOptionsMenu(Menu) -onCreateOptionsMenu()} callback method. Override this method in your Activity -and populate the {@link android.view.Menu} object given to you. You can populate the menu by -inflating a menu resource that was defined in XML, or by calling -{@link android.view.Menu#add(CharSequence) add()} -for each item you'd like in the menu. This method adds a {@link android.view.MenuItem}, and returns the -newly created object to you. You can use the returned MenuItem to set additional properties like -an icon, a keyboard shortcut, an intent, and other settings for the item.

+

Instead of instantiating {@link android.view.Menu} objects in your application code, you should +define a menu and all its items in an XML menu resource, then inflate the menu +resource (load it as a programmable object) in your application code. Defining your menus in XML is +a good practice because it separates your interface design from your application code (the same as +when you define your Activity +layout).

-

There are multiple {@link android.view.Menu#add(CharSequence) add()} methods. -Usually, you'll want to use one that accepts an itemId argument. -This is a unique integer that allows you to identify the item during a callback.

+

To define a menu, create an XML file inside your project's res/menu/ +directory and build the menu with the following elements:

+
+
<menu>
+
Creates a {@link android.view.Menu}, which is a container for menu items. It must be +the root node and holds one or more of the following elements. You can also nest this element +in an {@code <item>} to create a submenu.
+
<item>
+
Creates a {@link android.view.MenuItem}, which represents a single item in a menu.
+
<group>
+
An optional, invisible container for {@code <item>} elements. It allows you to +categorize menu items so they share properties such as active state and visibility. See Menu groups.
+
-

When a menu item is selected from the Options Menu, you will receive a callback to the -{@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} -method of your Activity. This callback passes you the -MenuItem that has been selected. You can identify the item by requesting the -itemId, with {@link android.view.MenuItem#getItemId() getItemId()}, -which returns the integer that was assigned with the add() method. Once you identify -the menu item, you can take the appropriate action.

+

For example, here is a file in res/menu/ named game_menu.xml:

+
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/new_game"
+          android:icon="@drawable/ic_new_game"
+          android:title="@string/new_game" />
+    <item android:id="@+id/quit"
+          android:icon="@drawable/ic_quit"
+          android:title="@string/quit" />
+</menu>
+
-

Here's an example of this procedure, inside an Activity, wherein we create an -Options Menu and handle item selections:

+

This example defines a menu with two menu items. Each item includes the attributes:

+
+
{@code android:id}
+
A resource ID that's unique to the item so that the application can recognize the item when +the user selects it.
+
{@code android:icon}
+
A drawable resource that is the icon visible to the user.
+
{@code android:title}
+
A string resource that is the title visible to the user.
+
+ +

For more about the XML syntax and attributes for a menu resource, see the Menu Resource reference.

+ + +

Inflating a Menu Resource

+ +

You can inflate your menu resource (convert the XML resource into a programmable object) using +{@link android.view.MenuInflater#inflate(int,Menu) MenuInflater.inflate()}. For +example, the following code inflates the game_menu.xml file defined above during the +{@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} callback method, to be +used for the Options Menu:

-/* Creates the menu items */
+@Override
 public boolean onCreateOptionsMenu(Menu menu) {
-    menu.add(0, MENU_NEW_GAME, 0, "New Game");
-    menu.add(0, MENU_QUIT, 0, "Quit");
+    MenuInflater inflater = getMenuInflater();
+    inflater.inflate(R.menu.game_menu, menu);
     return true;
 }
-
-/* Handles item selections */
-public boolean onOptionsItemSelected(MenuItem item) {
-    switch (item.getItemId()) {
-    case MENU_NEW_GAME:
-        newGame();
-        return true;
-    case MENU_QUIT:
-        quit();
-        return true;
-    }
-    return false;
-}
 
-

The add() method used in this sample takes four arguments: -groupId, itemId, order, and title. -The groupId allows you to associate this menu item with a group of other items -(more about Menu groups, below) — in -this example, we ignore it. itemId is a unique integer that we give the -MenuItem so that can identify it in the next callback. order allows us to -define the display order of the item — by default, they are displayed by the -order in which we add them. title is, of course, the name that goes on the -menu item (this can also be a -string resource, -and we recommend you do it that way for easier localization).

+

The {@link android.app.Activity#getMenuInflater()} method returns a {@link +android.view.MenuInflater} for the Activity. With this object, you can call {@link +android.view.MenuInflater#inflate(int,Menu) inflate()}, which inflates a menu resource into a +{@link android.view.Menu} object. In this example, the menu resource defined by +game_menu.xml +is inflated into the {@link android.view.Menu} that was passed into {@link +android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}. (This callback method for +creating an option menu is discussed more in the next section.)

-

Tip: -If you have several menu items that can be grouped together with a title, -consider organizing them into a Submenu.

-

Adding icons

-

Icons can also be added to items that appears in the Icon Menu with -{@link android.view.MenuItem#setIcon(Drawable) setIcon()}. For example:

+ +

Creating an Options Menu

+ +
+ +

Figure 1. Screenshot of an Options Menu.

+
+ + +

The Options Menu is where you should include basic application functions +and necessary navigation items (for example, a button +to open application settings). The user +can open the Options Menu with the device MENU key. +Figure 1 shows a screenshot of an Options Menu.

+ +

When opened, the first visible portion of the Options Menu is called the Icon Menu. It +holds the first six menu items. +If you add more than six items to the Options Menu, Android places the sixth item and those after it +into the Expanded Menu, which the user can open with the "More" menu item.

+ +

When the user opens the Options Menu for the first time, Android calls your Activity's +{@link android.app.Activity#onCreateOptionsMenu(Menu) +onCreateOptionsMenu()} method. Override this method in your Activity +and populate the {@link android.view.Menu} that is passed into the method. Populate the +{@link android.view.Menu} by inflating a menu resource as described in Inflating a Menu Resource. (You can +also populate the menu in code, using {@link android.view.Menu#add(int,int,int,int) +add()} to add menu items.)

+ +

When the user selects a menu item from the Options Menu, the system calls your Activity's +{@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} +method. This method passes the +{@link android.view.MenuItem} that the user selected. You can identify the menu item by calling +{@link android.view.MenuItem#getItemId()}, which returns the unique ID for the menu +item (defined by the {@code android:id} attribute in the menu resource or with an integer passed +to the {@link android.view.Menu#add(int,int,int,int) add()} method). You can match this ID +against known menu items and perform the appropriate action.

+ +

For example:

+
-menu.add(0, MENU_QUIT, 0, "Quit")
-    .setIcon(R.drawable.menu_quit_icon);
+@Override +public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection + switch (item.getItemId()) { + case R.id.new_game: + newGame(); + return true; + case R.id.quit: + quit(); + return true; + default: + return super.onOptionsItemSelected(item); + } +} + -

Modifying the menu

-

If you want to sometimes re-write the Options Menu as it is opened, override the -{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} method, which is -called each time the menu is opened. This will pass you the Menu object, just like the -onCreateOptionsMenu() callback. This is useful if you'd like to add or remove -menu options depending on the current state of an application or game.

+

In this example, {@link android.view.MenuItem#getItemId()} queries the ID for the selected menu +item and the switch statement compares the ID against the resource IDs that were assigned to menu +items in the XML resource. When a switch case successfully handles the item, it +returns "true" to indicate that the item selection was handled. Otherwise, the default statement +passes the menu item to the super class in +case it can handle the item selected. (If you've directly extended the {@link android.app.Activity} +class, then the super class returns "false", but it's a good practice to +pass unhandled menu items to the super class instead of directly returning "false".)

+ +

Tip: If your application contains multiple activities and +some of them provide the same Options Menu, consider creating +an Activity that implements nothing except the {@link android.app.Activity#onCreateOptionsMenu(Menu) +onCreateOptionsMenu()} and {@link android.app.Activity#onOptionsItemSelected(MenuItem) +onOptionsItemSelected()} methods. Then extend this class for each Activity that should share the +same Options Menu. This way, you have to manage only one set of code for handling menu +actions and each decendent class inherits the menu behaviors.

+If you want to add menu items to one of your decendent activities, +override {@link android.app.Activity#onCreateOptionsMenu(Menu) +onCreateOptionsMenu()} in that Activity. Call {@code super.onCreateOptionsMenu(menu)} so the +original menu items are created, then add new menu items with {@link +android.view.Menu#add(int,int,int,int) menu.add()}. You can also override the super class's +behavior for individual menu items.

+ + +

Changing the menu when it opens

+ +

The {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} method is +called only the first time the Options Menu is opened. The system keeps and re-uses the {@link +android.view.Menu} you define in this method until your Activity is destroyed. If you want to change +the Options Menu each time it opens, you must override the +{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} method. This passes +you the {@link android.view.Menu} object as it currently exists. This is useful if you'd like to +remove, add, disable, or enable menu items depending on the current state of your application.

Note: -When changing items in the menu, it's bad practice to do so based on the currently selected item. -Keep in mind that, when in touch mode, there will not be a selected (or focused) item. Instead, you -should use a Context Menu for such behaviors, when you want to provide -functionality based on a particular item in the UI.

+You should never change items in the Options Menu based on the {@link android.view.View} currently +in focus. When in touch mode (when the user is not using a trackball or d-pad), Views +cannot take focus, so you should never use focus as the basis for modifying +items in the Options Menu. If you want to provide menu items that are context-sensitive to a {@link +android.view.View}, use a Context Menu.

-

Context Menu

-

The Android context menu is similar, in concept, to the menu revealed with a "right-click" on a PC. -When a view is registered to a context menu, -performing a "long-press" (press and hold for about two seconds) on the object -will reveal a floating menu that provides functions relating to that item. -Context menus can be registered to any View object, -however, they are most often used for items in a -{@link android.widget.ListView}, which helpfully indicates the presence of the context menu -by transforming the background color of the ListView item when pressed. -(The items in the phone's contact list offer an example of this feature.) -

-

Note: Context menu items do not support icons or shortcut keys.

+

Creating a Context Menu

-

To create a context menu, you must override the Activity's context menu callback methods: -{@link android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) onCreateContextMenu()} and -{@link android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}. -Inside the onCreateContextMenu() callback method, you can add menu items using one of the -{@link android.view.Menu#add(CharSequence) add()} methods, or by -inflating a menu resource that was defined in XML. -Then, register a {@link android.view.ContextMenu} for the View, with -{@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()}.

+

A context menu is conceptually similar to the menu displayed when the user performs a +"right-click" on a PC. You should use a context menu to provide the user access to +actions that pertain to a specific item in the user interface. On Android, a context menu is +displayed when the user performs a "long press" (press and hold) on an item.

-

For example, here is some code that can be used with the -Notepad application -to add a context menu for each note in the list:

+

You can create a context menu for any View, though context menus are most often used for items in +a {@link android.widget.ListView}. When the user performs a long-press on an item in a ListView and +the list is registered to provide a context menu, the list item signals to the user that a context +menu is available by animating its background color—it transitions from +orange to white before opening the context menu. (The Contacts application demonstrates this +feature.)

+ + + +

In order for a View to provide a context menu, you must "register" the view for a context +menu. Call {@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()} and +pass it the {@link android.view.View} you want to give a context menu. When this View then +receives a long-press, it displays a context menu.

+ +

To define the context menu's appearance and behavior, override your Activity's context menu +callback methods, {@link android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) +onCreateContextMenu()} and +{@link android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}.

+ +

For example, here's an {@link +android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) +onCreateContextMenu()} that uses the {@code context_menu.xml} menu resource:

+@Override
 public void onCreateContextMenu(ContextMenu menu, View v,
                                 ContextMenuInfo menuInfo) {
   super.onCreateContextMenu(menu, v, menuInfo);
-  menu.add(0, EDIT_ID, 0, "Edit");
-  menu.add(0, DELETE_ID, 0,  "Delete");
+  MenuInflater inflater = getMenuInflater();
+  inflater.inflate(R.menu.context_menu, menu);
 }
+
+

{@link android.view.MenuInflater} is used to inflate the context menu from a menu resource. (You can also use +{@link android.view.Menu#add(int,int,int,int) add()} to add menu items.) The callback method +parameters include the {@link android.view.View} +that the user selected and a {@link android.view.ContextMenu.ContextMenuInfo} object that provides +additional information about the item selected. You might use these parameters to determine +which context menu should be created, but in this example, all context menus for the Activity are +the same.

+ +

Then when the user selects an item from the context menu, the system calls {@link +android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}. Here is an example +of how you can handle selected items:

+ +
+@Override
 public boolean onContextItemSelected(MenuItem item) {
   AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
   switch (item.getItemId()) {
-  case EDIT_ID:
+  case R.id.edit:
     editNote(info.id);
     return true;
-  case DELETE_ID:
+  case R.id.delete:
     deleteNote(info.id);
     return true;
   default:
@@ -205,285 +331,276 @@ public boolean onContextItemSelected(MenuItem item) {
 }
 
-

In onCreateContextMenu(), we are given not only the ContextMenu to -which we will add {@link android.view.MenuItem}s, but also the {@link android.view.View} -that was selected and a {@link android.view.ContextMenu.ContextMenuInfo ContextMenuInfo} object, -which provides additional information about the object that was selected. -In this example, nothing special is done in onCreateContextMenu() — just -a couple items are added as usual. In the onContextItemSelected() -callback, we request the {@link android.widget.AdapterView.AdapterContextMenuInfo AdapterContextMenuInfo} -from the {@code MenuItem}, which provides information about the currently selected item. -All we need from -this is the list ID for the selected item, so whether editing a note or deleting it, -we find the ID with the {@code AdapterContextMenuInfo.info} field of the object. This ID -is passed to the editNote() and deleteNote() methods to perform -the respective action.

+

The structure of this code is similar to the example for Creating an +Options Menu, in which {@link android.view.MenuItem#getItemId()} queries the ID for the selected +menu item and a switch statement matches the item to the IDs that are defined in the menu resource. +And like the options menu example, the default statement calls the super class in case it +can handle menu items not handled here, if necessary.

-

Now, to register this context menu for all the items in a {@link android.widget.ListView}, -we pass the entire {@code ListView} to the -{@link android.app.Activity#registerForContextMenu(View)} method:

+

In this example, the selected item is an item from a {@link android.widget.ListView}. To +perform an action on the selected item, the application needs to know the list +ID for the selected item (it's position in the ListView). To get the ID, the application calls +{@link android.view.MenuItem#getMenuInfo()}, which returns a {@link +android.widget.AdapterView.AdapterContextMenuInfo} object that includes the list ID for the +selected item in the {@link android.widget.AdapterView.AdapterContextMenuInfo#id id} field. The +local methods editNote() and deleteNote() methods accept this list ID to +perform an action on the data specified by the list ID.

-
registerForContextMenu(getListView());
-

Remember, you can pass any View object to register a context menu. Here, -{@link android.app.ListActivity#getListView()} returns the ListView -object used in the Notepad application's {@link android.app.ListActivity}. As such, each item -in the list is registered to this context menu.

+

Note: Items in a context menu do not support icons or shortcut +keys.

- -

A sub menu can be added within any menu, except another sub menu. -These are very useful when your application has a lot of functions that may be -organized in topics, like the items in a PC application's menu bar (File, Edit, View, etc.).

+ -

A sub menu is created by adding it to an existing {@link android.view.Menu} -with {@link android.view.Menu#addSubMenu(CharSequence) addSubMenu()}. -This returns a {@link android.view.SubMenu} object (an extension of {@link android.view.Menu}). -You can then add additional items to this menu, with the normal routine, using -the {@link android.view.Menu#add(CharSequence) add()} methods. For example:

+

A submenu is a menu that the user can open by selecting an item in another menu. You can add a +submenu to any menu (except a submenu). Submenus are useful when your application has a lot of +functions that can be organized into topics, like items in a PC application's menu bar (File, Edit, +View, etc.).

+ +

When creating your menu +resource, you can create a submenu by adding a {@code <menu>} element as the child of an +{@code <item>}. For example:

-public boolean onCreateOptionsMenu(Menu menu) {
-  boolean result = super.onCreateOptionsMenu(menu);
-
-  SubMenu fileMenu = menu.addSubMenu("File");
-  SubMenu editMenu = menu.addSubMenu("Edit");
-  fileMenu.add("new");
-  fileMenu.add("open");
-  fileMenu.add("save");
-  editMenu.add("undo");
-  editMenu.add("redo");
-
-  return result;
-}
-
-

Callbacks for items selected in a sub menu are made to the parent menu's callback method. -For the example above, selections in the sub menu will be handled by the -onOptionsItemSelected() callback.

-

You can also add Submenus when you define the parent menu in XML.

- - -

Define Menus in XML

-

Just like Android UI layouts, you can define application menus in XML, then inflate them -in your menu's onCreate...() callback method. This makes your application code cleaner and -separates more interface design into XML, which is easier to visualize.

- -

To start, create a new folder in your project res/ directory called menu. -This is where you should keep all XML files that define your application menus.

- -

In a menu XML layout, there are -three valid elements: <menu>, <group> and <item>. The -item and group elements must be children of a menu, but item -elements may also be the children of a group, and another menu element may be the child -of an item (to create a Submenu). Of course, the root node of any file -must be a menu element.

- -

As an example, we'll define the same menu created in the Options Menu section, -above. We start with an XML file named options_menu.xml inside the res/menu/ folder:

-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/new_game"
-          android:title="New Game" />
-    <item android:id="@+id/quit"
-          android:title="Quit" />
-</menu>
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/file"
+          android:icon="@drawable/file"
+          android:title="@string/file" >
+        <!-- "file" submenu -->
+        <menu">
+            <item android:id="@+id/new"
+                  android:title="@string/new" />
+            <item android:id="@+id/open"
+                  android:title="@string/open" />
+        </menu>
+    </item>
+</menu>
 
-

Then, in the onCreateOptionsMenu() method, we inflate this resource using -{@link android.view.MenuInflater#inflate(int,Menu) MenuInflater.inflate()}:

-
-public boolean onCreateOptionsMenu(Menu menu) {
-    MenuInflater inflater = getMenuInflater();
-    inflater.inflate(R.menu.options_menu, menu);
-    return true;
-}
-
+

When the user selects an item from a submenu, the parent menu's respective on-item-selected +callback method receives the event. For instance, if the above menu is applied as an Options Menu, +then the {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} method +is called when a submenu item is selected.

-

The {@link android.app.Activity#getMenuInflater()} method returns the {@link android.view.MenuInflater} -for our activity's context. We then call {@link android.view.MenuInflater#inflate(int,Menu) inflate()}, -passing it a pointer to our menu resource and the Menu object given by the callback.

+

You can also use {@link android.view.Menu#addSubMenu(int,int,int,int) addSubMenu()} to +dynamically add a {@link android.view.SubMenu} to an existing {@link android.view.Menu}. This +returns the new {@link android.view.SubMenu} object, to which you can add +submenu items, using {@link android.view.Menu#add(int,int,int,int) add()}

-

While this small sample may seem like more effort, compared to creating the menu items in the -onCreateOptionsMenu() method, this will save a lot of trouble when dealing with more items -and it keeps your application code clean.

-

You can define menu groups by wrapping item elements in a group -element, and create Submenus by nesting another menu inside an item. -Each element also supports all the necessary attributes to control features like shortcut keys, -checkboxes, icons, and more. To learn about these attributes and more about the XML syntax, see the Menus -topic in the Available -Resource Types document.

-

Menu Features

-

Here are some other features that can be applied to most menu items.

+

Other Menu Features

+ +

Here are some other features that you can apply to most menu items.

Menu groups

-

When adding new items to a menu, you can optionally include each item in a group. -A menu group is a collection of menu items that can share certain traits, like -whether they are visible, enabled, or checkable.

-

A group is defined by an integer (or a resource id, in XML). A menu item is added to the group when it is -added to the menu, using one of the add() methods that accepts a groupId -as an argument, such as {@link android.view.Menu#add(int,int,int,int)}.

+

A menu group is a collection of menu items that share certain traits. With a group, you +can:

+ + +

You can create a group by nesting {@code <item>} elements inside a {@code <group>} +element in your menu resource or by specifying a group ID with the the {@link +android.view.Menu#add(int,int,int,int) add()} method.

+ +

Here's an example menu resource that includes a group:

+ +
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/item1"
+          android:icon="@drawable/item1"
+          android:title="@string/item1" />
+    <!-- menu group -->
+    <group android:id="@+id/group1">
+        <item android:id="@+id/groupItem1"
+              android:title="@string/groupItem1" />
+        <item android:id="@+id/groupItem2"
+              android:title="@string/groupItem2" />
+    </group>
+</menu>
+
+ +

The items that are in the group appear the same as the first item that is not in a +group—all three items in the menu are siblings. However, you can modify the traits of the two +items in the group by referencing the group ID and using the methods listed above.

-

You can show or hide the entire group with -{@link android.view.Menu#setGroupVisible(int,boolean) setGroupVisible()}; -enable or disable the group with -{@link android.view.Menu#setGroupEnabled(int,boolean) setGroupEnabled()}; -and set whether the items can be checkable with -{@link android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}. -

Checkable menu items

- -

Any menu item can be used as an interface for turning options on and off. This can -be indicated with a checkbox for stand-alone options, or radio buttons for groups of -mutually exclusive options (see the screenshot, to the right).

-

Note: Menu items in the Icon Menu cannot +

+ +

Figure 2. Screenshot of checkable menu items

+
+ +

A menu can be useful as an interface for turning options on and off, using a checkbox for +stand-alone options, or radio buttons for groups of +mutually exclusive options. Figure 2 shows a submenu with items that are checkable with radio +buttons.

+ +

Note: Menu items in the Icon Menu (from the Options Menu) cannot display a checkbox or radio button. If you choose to make items in the Icon Menu checkable, -then you must personally indicate the state by swapping the icon and/or text -each time the state changes between on and off.

+you must manually indicate the checked state by swapping the icon and/or text +each time the state changes.

+ +

You can define the checkable behavior for individual menu items using the {@code +android:checkable} attribute in the {@code <item>} element, or for an entire group with +the {@code android:checkableBehavior} attribute in the {@code <group>} element. For +example, all items in this menu group are checkable with a radio button:

-

To make a single item checkable, use the {@link android.view.MenuItem#setCheckable(boolean) -setCheckable()} method, like so:

-menu.add(0, VIBRATE_SETTING_ID, 0, "Vibrate")
-    .setCheckable(true);
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <group android:checkableBehavior="single">
+        <item android:id="@+id/red"
+              android:title="@string/red" />
+        <item android:id="@+id/blue"
+              android:title="@string/blue" />
+    </group>
+</menu>
 
-

This will display a checkbox with the menu item (unless it's in the Icon Menu). When the item -is selected, the onOptionsItemSelected() callback is called as usual. It is here that -you must set the state of the checkbox. You can query the current state of the item with -{@link android.view.MenuItem#isChecked()} and set the checked state with -{@link android.view.MenuItem#setChecked(boolean) setChecked()}. -Here's what this looks like inside the -onOptionsItemSelected() callback:

+ +

The {@code android:checkableBehavior} attribute accepts either: +

+
{@code single}
+
Only one item from the group can be checked (radio buttons)
+
{@code all}
+
All items can be checked (checkboxes)
+
{@code none}
+
No items are checkable
+
+ +

You can apply a default checked state to an item using the {@code android:checked} attribute in +the {@code <item>} element and change it in code with the {@link +android.view.MenuItem#setChecked(boolean) setChecked()} method.

+ +

When a checkable item is selected, the system calls your respective item-selected callback method +(such as {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}). It +is here that you must set the state of the checkbox, because a checkbox or radio button does not +change its state automatically. You can query the current state of the item (as it was before the +user selected it) with {@link android.view.MenuItem#isChecked()} and then set the checked state with +{@link android.view.MenuItem#setChecked(boolean) setChecked()}. For example:

+
-switch (item.getItemId()) {
-case VIBRATE_SETTING_ID:
-  if (item.isChecked()) item.setChecked(false);
-  else item.setChecked(true);
-  return true;
-...
+@Override
+public boolean onOptionsItemSelected(MenuItem item) {
+  switch (item.getItemId()) {
+  case R.id.vibrate:
+  case R.id.dont_vibrate:
+    if (item.isChecked()) item.setChecked(false);
+    else item.setChecked(true);
+    return true;
+  default:
+    return super.onOptionsItemSelected(item);
+  }
 }
 
-

To make a group of mutually exclusive radio button items, simply -assign the same group ID to each menu item -and call {@link android.view.Menu#setGroupCheckable(int,boolean,boolean) -setGroupCheckable()}. In this case, you don't need to call setCheckable() -on each menu items, because the group as a whole is set checkable. Here's an example of -two mutually exclusive options in a Submenu:

-
-SubMenu subMenu = menu.addSubMenu("Color");
-subMenu.add(COLOR_MENU_GROUP, COLOR_RED_ID, 0, "Red");
-subMenu.add(COLOR_MENU_GROUP, COLOR_BLUE_ID, 0, "Blue");
-subMenu.setGroupCheckable(COLOR_MENU_GROUP, true, true);
-
-

In the setGroupCheckable() method, the first argument is the group ID -that we want to set checkable. The second argument is whether we want the group items -to be checkable. The last one is whether we want each item to be exclusively checkable -(if we set this false, then all the items will be checkboxes instead of radio buttons). -When the group is set to be exclusive (radio buttons), each time a new item is selected, -all other are automatically de-selected.

-

+

If you don't set the checked state this way, then the visible state of the item (the checkbox or +radio button) will not +change when the user selects it. When you do set the state, the Activity preserves the checked state +of the item so that when the user opens the menu later, the checked state that you +set is visible.

Note: -Checkable menu items are intended to be used only on a per-session basis and not saved to the device -(e.g., the Map mode setting in the Maps application is not saved — screenshot above). -If there are application settings that you would like to save for the user, -then you should store the data using Preferences, -and manage them with a {@link android.preference.PreferenceActivity}.

+Checkable menu items are intended to be used only on a per-session basis and not saved after the +application is destroyed. If you have application settings that you would like to save for the user, +you should store the data using Shared Preferences.

Shortcut keys

-

Quick access shortcut keys using letters and/or numbers can be added to menu items with -setAlphabeticShortcut(char) (to set char shortcut), setNumericShortcut(int) -(to set numeric shortcut), -or setShortcut(char,int) (to set both). Case is not sensitive. -For example:

-
-menu.add(0, MENU_QUIT, 0, "Quit")
-    .setAlphabeticShortcut('q');
-
-

Now, when the menu is open (or while holding the MENU key), pressing the "q" key will -select this item.

-

This shortcut key will be displayed as a tip in the menu item, below the menu item name -(except for items in the Icon Menu).

-

Note: Shortcuts cannot be added to items in a Context Menu.

+

You can add quick-access shortcut keys using letters and/or numbers to menu items with the +{@code android:alphabeticShortcut} and {@code android:numericShortcut} attributes in the {@code +<item>} element. You can also use the methods {@link +android.view.MenuItem#setAlphabeticShortcut(char)} and {@link +android.view.MenuItem#setNumericShortcut(char)}. Shortcut keys are not +case sensitive.

+ +

For example, if you apply the "s" character as an alphabetic shortcut to a "save" menu item, then +when the menu is open (or while the user holds the MENU key) and the user presses the "s" key, +the "save" menu item is selected.

+ +

This shortcut key is displayed as a tip in the menu item, below the menu item name +(except for items in the Icon Menu, which are displayed only if the user holds the MENU +key).

+ +

Note: Shortcut keys for menu items only work on devices with a +hardware keyboard. Shortcuts cannot be added to items in a Context Menu.

-

Menu item intents

-

If you've read the Application -Fundamentals, then you're at least a little familiar -with Android Intents. These allow applications to bind with each other, share information, -and perform user tasks cooperatively. Just like your application might fire an Intent to launch a web browser, -an email client, or another Activity in your application, -you can perform such actions from within a menu. -There are two ways to do this: define an Intent and assign it to a single menu item, or -define an Intent and allow Android to search the device for activities and dynamically add a -menu item for each one that meets the Intent criteria.

+

Intents for menu items

-

For more information on creating Intents and providing your application's services to other applications, -read the Intents -and Intent Filters document.

+

Sometimes you'll want a menu item to launch an Activity using an Intent (whether it's an +Actvitity in your application or another application). When you know the Intent you want to use and +have a specific menu item that should initiate the Intent, you can execute the Intent with {@link +android.app.Activity#startActivity(Intent) startActivity()} during the appropriate on-item-selected +callback method (such as the {@link android.app.Activity#onOptionsItemSelected(MenuItem) +onOptionsItemSelected()} callback).

-

Set an intent for a single menu item

-

If you want to offer a specific menu item that launches a new Activity, then you -can specifically define an Intent for the menu item with the -{@link android.view.MenuItem#setIntent(Intent) -setIntent()} method.

+

However, if you are not certain that the user's device +contains an application that handles the Intent, then adding a menu item that executes the +Intent can result in a non-functioning menu item, because the Intent might not resolve to an +Activity that accepts it. To solve this, Android lets you dynamically add menu items to your menu +when Android finds activities on the device that handle your Intent.

-

For example, inside the {@link android.app.Activity#onCreateOptionsMenu(Menu) -onCreateOptionsMenu()} method, you can define a new menu item with an Intent like this:

-
-MenuItem menuItem = menu.add(0, PHOTO_PICKER_ID, 0, "Select Photo");
-menuItem.setIntent(new Intent(this, PhotoPicker.class));
-
-

Android will automatically launch the Activity when the item is selected.

+

If you're not familiar with creating Intents, read the Intents and Intent Filters.

-

Note: This will not return a result to your Activity. -If you wish to be returned a result, then do not use setIntent(). -Instead, handle the selection as usual in the onOptionsMenuItemSelected() -or onContextMenuItemSelected() callback and call -{@link android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()}. -

-

Dynamically add intents

+

Dynamically adding Intents

-

If there are potentially multiple activities that are relevant to your current -Activity or selected item, then the application can dynamically add menu items that execute other -services.

-

During menu creation, define an Intent with the category Intent.ALTERNATIVE_CATEGORY and/or -Intent.SELECTED_ALTERNATIVE, the MIME type currently selected (if any), and any other -requirements, the same way as you would satisfy an intent filter to open a new -Activity. Then call -{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) -addIntentOptions()} to have Android search for any services meeting those requirements -and add them to the menu for you. If there are no applications installed -that satisfy the Intent, then no additional menu items are added.

+

When you don't know if the user's device has an application that handles a specific Intent, +you can define the Intent and let Android search the device for activities that accept the Intent. +When it finds activies that handle the Intent, it adds a menu item for +each one to your menu and attaches the appropriate Intent to open the Activity when the user +selects it.

+ +

To add menu items based on available activities that accept an Intent:

+
    +
  1. Define an +Intent with the category {@link android.content.Intent#CATEGORY_ALTERNATIVE} and/or +{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE}, plus any other requirements.
  2. +
  3. Call {@link +android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) +Menu.addIntentOptions()}. Android then searches for any applications that can perform the Intent +and adds them to your menu.
  4. +
+ +

If there are no applications installed +that satisfy the Intent, then no menu items are added.

Note: -SELECTED_ALTERNATIVE is used to handle the currently selected element on the -screen. So, it should only be used when creating a Menu in onCreateContextMenu() or -onPrepareOptionsMenu(), which is called every time the Options Menu is opened.

+{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} is used to handle the currently +selected element on the screen. So, it should only be used when creating a Menu in {@link +android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) +onCreateContextMenu()}.

-

Here's an example demonstrating how an application would search for -additional services to display on its menu.

+

For example:

+@Override
 public boolean onCreateOptionsMenu(Menu menu){
     super.onCreateOptionsMenu(menu);
 
     // Create an Intent that describes the requirements to fulfill, to be included
-    // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE. 
-    Intent intent = new Intent(null, getIntent().getData());
+    // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
+    Intent intent = new Intent(null, dataUri);
     intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
-        
-    // Search for, and populate the menu with, acceptable offering applications.
+
+    // Search and populate the menu with acceptable offering applications.
     menu.addIntentOptions(
-         thisClass.INTENT_OPTIONS,  // Menu group 
+         R.id.intent_group,  // Menu group to which new items will be added
          0,      // Unique item ID (none)
          0,      // Order for the items (none)
          this.getComponentName(),   // The current Activity name
@@ -495,17 +612,27 @@ public boolean onCreateOptionsMenu(Menu menu){
     return true;
 }
-

For each Activity found that provides an Intent Filter matching the Intent defined, a menu -item will be added, using the android:label value of the intent filter as the text -for the menu item. -The {@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) addIntentOptions()} method will also return the number of menu items added.

-

Also be aware that, when addIntentOptions() is called, it will override any and all -menu items in the menu group specified in the first argument.

+

For each Activity found that provides an Intent filter matching the Intent defined, a menu +item is added, using the value in the Intent filter's android:label as the +menu item title and the application icon as the menu item icon. The +{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) +addIntentOptions()} method returns the number of menu items added.

-

If you wish to offer the services of your Activity to other application menus, then you -only need to define an intent filter as usual. Just be sure to include the ALTERNATIVE and/or -SELECTED_ALTERNATIVE values in the name attribute of -a <category> element in the intent filter. For example:

+

Note: When you call {@link +android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) +addIntentOptions()}, it overrides any and all menu items by the menu group specified in the first +argument.

+ + +

Allowing your Activity to be added to menus

+ +

You can also offer the services of your Activity to other applications, so your +application can be included in the menu of others (reverse the roles described above).

+ +

To be included in other application menus, you need to define an Intent +filter as usual, but be sure to include the {@link android.content.Intent#CATEGORY_ALTERNATIVE} +and/or {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} values for the Intent filter +category. For example:

 <intent-filter label="Resize Image">
     ...
@@ -514,9 +641,10 @@ a <category> element in the intent filter. For example:

... </intent-filter>
-

read more about writing intent filters in the + +

Read more about writing Intent filters in the Intents and Intent Filters document.

For a sample application using this technique, see the -Note Pad -sample code.

+Note +Pad sample code.