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
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:
-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.
+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><item><group>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:
+For more about the XML syntax and attributes for a menu resource, see the Menu Resource reference.
+ + +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.
-Icons can also be added to items that appears in the Icon Menu with
-{@link android.view.MenuItem#setIcon(Drawable) setIcon()}. For example:
+ 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); + } +} + -
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.
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. -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.
+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.)
+ +If your Activity uses a {@link android.widget.ListView} and +you want all list items to provide a context menu, register all items for a context +menu by passing the {@link android.widget.ListView} to {@link +android.app.Activity#registerForContextMenu(View) registerForContextMenu()}. For +example, if you're using a {@link android.app.ListActivity}, register all list items like this:
+registerForContextMenu({@link android.app.ListActivity#getListView()});
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.
- - -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.
Here are some other features that can be applied to most menu items.
+Here are some other features that you can apply to most menu items.
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()}.
-
-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: +
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.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.
-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.
+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).
-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()}.
-
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:
+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.
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.
+ + +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.