The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | page.title=Creating Menus |
| 2 | parent.title=User Interface |
| 3 | parent.link=index.html |
| 4 | @jd:body |
| 5 | |
| 6 | <div id="qv-wrapper"> |
| 7 | <div id="qv"> |
| 8 | <h2>Key classes</h2> |
| 9 | <ol> |
| 10 | <li>{@link android.view.Menu}</li> |
| 11 | <li>{@link android.view.ContextMenu}</li> |
| 12 | <li>{@link android.view.SubMenu}</li> |
| 13 | </ol> |
| 14 | <h2>In this document</h2> |
| 15 | <ol> |
| 16 | <li><a href="#options-menu">Options Menu</a></li> |
| 17 | <li><a href="#context-menu">Context Menu</a></li> |
| 18 | <li><a href="#submenu">Submenu</a></li> |
| 19 | <li><a href="#xml">Define Menus in XML</a></li> |
| 20 | <li><a href="#features">Menu Features</a> |
| 21 | <ol> |
| 22 | <li><a href="#groups">Menu groups</a></li> |
| 23 | <li><a href="#checkable">Checkable menu items</a></li> |
| 24 | <li><a href="#shortcuts">Shortcut keys</a></li> |
| 25 | <li><a href="#intents">Menu item intents</a></li> |
| 26 | </ol> |
| 27 | </li> |
| 28 | </ol> |
| 29 | </div> |
| 30 | </div> |
| 31 | |
| 32 | <p>Menus are an important part of any application. They provide familiar interfaces |
| 33 | that reveal application functions and settings. Android offers an easy programming interface |
| 34 | for developers to provide standardized application menus for various situations.</p> |
| 35 | |
| 36 | <p>Android offers three fundamental types of application menus:</p> |
| 37 | <dl> |
| 38 | <dt><strong>Options Menu</strong></dt> |
| 39 | <dd>This is the primary set of menu items for an Activity. It is revealed by pressing |
| 40 | the device MENU key. Within the Options Menu are two groups of menu items: |
| 41 | <dl style="margin-top:1em"> |
| 42 | <dt><em>Icon Menu</em></dt> |
| 43 | <dd>This is the collection of items initially visible at the bottom of the screen |
| 44 | at the press of the MENU key. It supports a maximum of six menu items. |
| 45 | These are the only menu items that support icons and the only menu items that <em>do not</em> support |
| 46 | checkboxes or radio buttons.</dd> |
| 47 | <dt><em>Expanded Menu</em></dt> |
| 48 | <dd>This is a vertical list of items exposed by the "More" menu item from the Icon Menu. |
| 49 | It exists only when the Icon Menu becomes over-loaded and is comprised of the sixth |
| 50 | Option Menu item and the rest.</dd> |
| 51 | </dl> |
| 52 | </dd> |
| 53 | <dt><strong>Context Menu</strong></dt> |
| 54 | <dd>This is a floating list of menu items that may appear when you perform a long-press on a View |
| 55 | (such as a list item). </dd> |
| 56 | <dt><strong>Submenu</strong></dt> |
| 57 | <dd>This is a floating list of menu items that is revealed by an item in the Options Menu |
| 58 | or a Context Menu. A Submenu item cannot support nested Submenus. </dd> |
| 59 | </dl> |
| 60 | |
| 61 | |
| 62 | <h2 id="options-menu">Options Menu</h2> |
| 63 | <img align="right" src="{@docRoot}images/options_menu.png" /> |
| 64 | <p>The Options Menu is opened by pressing the device MENU key. |
| 65 | When opened, the Icon Menu is displayed, which holds the first six menu items. |
| 66 | If more than six items are added to the Options Menu, then those that can't fit |
| 67 | in the Icon Menu are revealed in the Expanded Menu, via the "More" menu item. The Expanded Menu |
| 68 | is automatically added when there are more than six items.</p> |
| 69 | |
| 70 | <p>The Options Menu is where you should include basic application functions |
| 71 | and any necessary navigation items (e.g., to a home screen or application settings). |
| 72 | You can also add <a href="#submenu">Submenus</a> for organizing topics |
| 73 | and including extra menu functionality.</p> |
| 74 | |
| 75 | <p>When this menu is opened for the first time, |
| 76 | the Android system will call the Activity <code>{@link android.app.Activity#onCreateOptionsMenu(Menu) |
| 77 | onCreateOptionsMenu()}</code> callback method. Override this method in your Activity |
| 78 | and populate the {@link android.view.Menu} object given to you. You can populate the menu by |
| 79 | inflating a menu resource that was <a href="#xml">defined in XML</a>, or by calling |
| 80 | <code>{@link android.view.Menu#add(CharSequence) add()}</code> |
| 81 | for each item you'd like in the menu. This method adds a {@link android.view.MenuItem}, and returns the |
| 82 | newly created object to you. You can use the returned MenuItem to set additional properties like |
| 83 | an icon, a keyboard shortcut, an intent, and other settings for the item.</p> |
| 84 | |
| 85 | <p>There are multiple <code>{@link android.view.Menu#add(CharSequence) add()}</code> methods. |
| 86 | Usually, you'll want to use one that accepts an <var>itemId</var> argument. |
| 87 | This is a unique integer that allows you to identify the item during a callback.</p> |
| 88 | |
Elliott Hughes | 7f87706 | 2009-07-30 17:00:34 -0700 | [diff] [blame^] | 89 | <p>When a menu item is selected from the Options Menu, you will receive a callback to the |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 90 | <code>{@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}</code> |
| 91 | method of your Activity. This callback passes you the |
| 92 | <code>MenuItem</code> that has been selected. You can identify the item by requesting the |
| 93 | <var>itemId</var>, with <code>{@link android.view.MenuItem#getItemId() getItemId()}</code>, |
| 94 | which returns the integer that was assigned with the <code>add()</code> method. Once you identify |
| 95 | the menu item, you can take the appropriate action.</p> |
| 96 | |
| 97 | <p>Here's an example of this procedure, inside an Activity, wherein we create an |
| 98 | Options Menu and handle item selections:</p> |
| 99 | |
| 100 | <pre> |
| 101 | /* Creates the menu items */ |
| 102 | public boolean onCreateOptionsMenu(Menu menu) { |
| 103 | menu.add(0, MENU_NEW_GAME, 0, "New Game"); |
| 104 | menu.add(0, MENU_QUIT, 0, "Quit"); |
| 105 | return true; |
| 106 | } |
| 107 | |
| 108 | /* Handles item selections */ |
| 109 | public boolean onOptionsItemSelected(MenuItem item) { |
| 110 | switch (item.getItemId()) { |
| 111 | case MENU_NEW_GAME: |
| 112 | newGame(); |
| 113 | return true; |
| 114 | case MENU_QUIT: |
| 115 | quit(); |
| 116 | return true; |
| 117 | } |
| 118 | return false; |
| 119 | } |
| 120 | </pre> |
| 121 | |
| 122 | <p>The <code>add()</code> method used in this sample takes four arguments: |
| 123 | <var>groupId</var>, <var>itemId</var>, <var>order</var>, and <var>title</var>. |
| 124 | The <var>groupId</var> allows you to associate this menu item with a group of other items |
| 125 | (more about <a href="#groups">Menu groups</a>, below) — in |
| 126 | this example, we ignore it. <var>itemId</var> is a unique integer that we give the |
| 127 | MenuItem so that can identify it in the next callback. <var>order</var> allows us to |
| 128 | define the display order of the item — by default, they are displayed by the |
| 129 | order in which we add them. <var>title</var> is, of course, the name that goes on the |
| 130 | menu item (this can also be a |
| 131 | <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">string resource</a>, |
| 132 | and we recommend you do it that way for easier localization).</p> |
| 133 | |
| 134 | <p class="note"><strong>Tip:</strong> |
| 135 | If you have several menu items that can be grouped together with a title, |
| 136 | consider organizing them into a <a href="#submenu">Submenu</a>.</p> |
| 137 | |
| 138 | <h3>Adding icons</h3> |
| 139 | <p>Icons can also be added to items that appears in the Icon Menu with |
| 140 | <code>{@link android.view.MenuItem#setIcon(Drawable) setIcon()}</code>. For example:</p> |
| 141 | <pre> |
| 142 | menu.add(0, MENU_QUIT, 0, "Quit") |
| 143 | .setIcon(R.drawable.menu_quit_icon);</pre> |
| 144 | |
| 145 | <h3>Modifying the menu</h3> |
| 146 | <p>If you want to sometimes re-write the Options Menu as it is opened, override the |
| 147 | <code>{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}</code> method, which is |
| 148 | called each time the menu is opened. This will pass you the Menu object, just like the |
| 149 | <code>onCreateOptionsMenu()</code> callback. This is useful if you'd like to add or remove |
| 150 | menu options depending on the current state of an application or game.</p> |
| 151 | |
| 152 | <p class="note"><strong>Note:</strong> |
| 153 | When changing items in the menu, it's bad practice to do so based on the currently selected item. |
| 154 | Keep in mind that, when in touch mode, there will not be a selected (or focused) item. Instead, you |
| 155 | should use a <a href="#context-menu">Context Menu</a> for such behaviors, when you want to provide |
| 156 | functionality based on a particular item in the UI.</p> |
| 157 | |
| 158 | |
| 159 | <h2 id="context-menu">Context Menu</h2> |
| 160 | <p>The Android context menu is similar, in concept, to the menu revealed with a "right-click" on a PC. |
| 161 | When a view is registered to a context menu, |
| 162 | performing a "long-press" (press and hold for about two seconds) on the object |
| 163 | will reveal a floating menu that provides functions relating to that item. |
| 164 | Context menus can be registered to any View object, |
| 165 | however, they are most often used for items in a |
| 166 | {@link android.widget.ListView}, which helpfully indicates the presence of the context menu |
| 167 | by transforming the background color of the ListView item when pressed. |
| 168 | (The items in the phone's contact list offer an example of this feature.) |
| 169 | </p> |
| 170 | |
| 171 | <p class="note"><strong>Note:</strong> Context menu items do not support icons or shortcut keys.</p> |
| 172 | |
| 173 | <p>To create a context menu, you must override the Activity's context menu callback methods: |
| 174 | <code>{@link android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) onCreateContextMenu()}</code> and |
| 175 | <code>{@link android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}</code>. |
| 176 | Inside the <code>onCreateContextMenu()</code> callback method, you can add menu items using one of the |
| 177 | <code>{@link android.view.Menu#add(CharSequence) add()}</code> methods, or by |
| 178 | inflating a menu resource that was <a href="#xml">defined in XML</a>. |
| 179 | Then, register a {@link android.view.ContextMenu} for the View, with |
| 180 | <code>{@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()}</code>.</p> |
| 181 | |
| 182 | <p>For example, here is some code that can be used with the |
| 183 | <a href="{@docRoot}guide/tutorials/notepad/index.html">Notepad application</a> |
| 184 | to add a context menu for each note in the list:</p> |
| 185 | <pre> |
| 186 | public void onCreateContextMenu(ContextMenu menu, View v, |
| 187 | ContextMenuInfo menuInfo) { |
| 188 | super.onCreateContextMenu(menu, v, menuInfo); |
| 189 | menu.add(0, EDIT_ID, 0, "Edit"); |
| 190 | menu.add(0, DELETE_ID, 0, "Delete"); |
| 191 | } |
| 192 | |
| 193 | public boolean onContextItemSelected(MenuItem item) { |
| 194 | AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); |
| 195 | switch (item.getItemId()) { |
| 196 | case EDIT_ID: |
| 197 | editNote(info.id); |
| 198 | return true; |
| 199 | case DELETE_ID: |
| 200 | deleteNote(info.id); |
| 201 | return true; |
| 202 | default: |
| 203 | return super.onContextItemSelected(item); |
| 204 | } |
| 205 | } |
| 206 | </pre> |
| 207 | |
| 208 | <p>In <code>onCreateContextMenu()</code>, we are given not only the ContextMenu to |
| 209 | which we will add {@link android.view.MenuItem}s, but also the {@link android.view.View} |
| 210 | that was selected and a {@link android.view.ContextMenu.ContextMenuInfo ContextMenuInfo} object, |
| 211 | which provides additional information about the object that was selected. |
| 212 | In this example, nothing special is done in <code>onCreateContextMenu()</code> — just |
| 213 | a couple items are added as usual. In the <code>onContextItemSelected()</code> |
| 214 | callback, we request the {@link android.widget.AdapterView.AdapterContextMenuInfo AdapterContextMenuInfo} |
| 215 | from the {@code MenuItem}, which provides information about the currently selected item. |
| 216 | All we need from |
| 217 | this is the list ID for the selected item, so whether editing a note or deleting it, |
| 218 | we find the ID with the {@code AdapterContextMenuInfo.info} field of the object. This ID |
Elliott Hughes | 7f87706 | 2009-07-30 17:00:34 -0700 | [diff] [blame^] | 219 | is passed to the <code>editNote()</code> and <code>deleteNote()</code> methods to perform |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 220 | the respective action.</p> |
| 221 | |
| 222 | <p>Now, to register this context menu for all the items in a {@link android.widget.ListView}, |
| 223 | we pass the entire {@code ListView} to the |
| 224 | <code>{@link android.app.Activity#registerForContextMenu(View)}</code> method:</p> |
| 225 | |
| 226 | <pre>registerForContextMenu(getListView());</pre> |
| 227 | <p>Remember, you can pass any View object to register a context menu. Here, |
| 228 | <code>{@link android.app.ListActivity#getListView()}</code> returns the ListView |
| 229 | object used in the Notepad application's {@link android.app.ListActivity}. As such, each item |
| 230 | in the list is registered to this context menu.</p> |
| 231 | |
| 232 | |
| 233 | |
| 234 | <h2 id="submenu">Submenus</h2> |
| 235 | <p>A sub menu can be added within any menu, except another sub menu. |
| 236 | These are very useful when your application has a lot of functions that may be |
| 237 | organized in topics, like the items in a PC application's menu bar (File, Edit, View, etc.).</p> |
| 238 | |
| 239 | <p>A sub menu is created by adding it to an existing {@link android.view.Menu} |
| 240 | with <code>{@link android.view.Menu#addSubMenu(CharSequence) addSubMenu()}</code>. |
| 241 | This returns a {@link android.view.SubMenu} object (an extension of {@link android.view.Menu}). |
| 242 | You can then add additional items to this menu, with the normal routine, using |
| 243 | the <code>{@link android.view.Menu#add(CharSequence) add()}</code> methods. For example:</p> |
| 244 | |
| 245 | <pre> |
| 246 | public boolean onCreateOptionsMenu(Menu menu) { |
| 247 | boolean result = super.onCreateOptionsMenu(menu); |
| 248 | |
| 249 | SubMenu fileMenu = menu.addSubMenu("File"); |
| 250 | SubMenu editMenu = menu.addSubMenu("Edit"); |
| 251 | fileMenu.add("new"); |
| 252 | fileMenu.add("open"); |
| 253 | fileMenu.add("save"); |
| 254 | editMenu.add("undo"); |
| 255 | editMenu.add("redo"); |
| 256 | |
| 257 | return result; |
| 258 | } |
| 259 | </pre> |
| 260 | <p>Callbacks for items selected in a sub menu are made to the parent menu's callback method. |
| 261 | For the example above, selections in the sub menu will be handled by the |
| 262 | <code>onOptionsItemSelected()</code> callback.</p> |
| 263 | <p>You can also add Submenus when you <a href="#xml">define the parent menu in XML</a>.</p> |
| 264 | |
| 265 | |
| 266 | <h2 id="xml">Define Menus in XML</h2> |
| 267 | <p>Just like Android UI layouts, you can define application menus in XML, then inflate them |
| 268 | in your menu's <code>onCreate...()</code> callback method. This makes your application code cleaner and |
| 269 | separates more interface design into XML, which is easier to visualize.</p> |
| 270 | |
| 271 | <p>To start, create a new folder in your project <code>res/</code> directory called <code>menu</code>. |
| 272 | This is where you should keep all XML files that define your application menus.</p> |
| 273 | |
| 274 | <p>In a menu XML layout, there are |
| 275 | three valid elements: <code><menu></code>, <code><group></code> and <code><item></code>. The |
| 276 | <code>item</code> and <code>group</code> elements must be children of a <code>menu</code>, but <code>item</code> |
| 277 | elements may also be the children of a <code>group</code>, and another <code>menu</code> element may be the child |
| 278 | of an <code>item</code> (to create a Submenu). Of course, the root node of any file |
| 279 | must be a <code>menu</code> element.</p> |
| 280 | |
| 281 | <p>As an example, we'll define the same menu created in the <a href="#options-menu">Options Menu</a> section, |
| 282 | above. We start with an XML file named <code>options_menu.xml</code> inside the <code>res/menu/</code> folder:</p> |
| 283 | <pre> |
| 284 | <menu xmlns:android="http://schemas.android.com/apk/res/android"> |
| 285 | <item android:id="@+id/new_game" |
| 286 | android:title="New Game" /> |
| 287 | <item android:id="@+id/quit" |
| 288 | android:title="Quit" /> |
| 289 | </menu> |
| 290 | </pre> |
| 291 | |
| 292 | <p>Then, in the <code>onCreateOptionsMenu()</code> method, we inflate this resource using |
| 293 | <code>{@link android.view.MenuInflater#inflate(int,Menu) MenuInflater.inflate()}</code>:</p> |
| 294 | <pre> |
| 295 | public boolean onCreateOptionsMenu(Menu menu) { |
| 296 | MenuInflater inflater = getMenuInflater(); |
| 297 | inflater.inflate(R.menu.options_menu, menu); |
| 298 | return true; |
| 299 | } |
| 300 | </pre> |
| 301 | |
| 302 | <p>The <code>{@link android.app.Activity#getMenuInflater()}</code> method returns the {@link android.view.MenuInflater} |
| 303 | for our activity's context. We then call <code>{@link android.view.MenuInflater#inflate(int,Menu) inflate()}</code>, |
| 304 | passing it a pointer to our menu resource and the Menu object given by the callback.</code></p> |
| 305 | |
| 306 | <p>While this small sample may seem like more effort, compared to creating the menu items in the |
| 307 | <code>onCreateOptionsMenu()</code> method, this will save a lot of trouble when dealing with more items |
| 308 | and it keeps your application code clean.</p> |
| 309 | |
| 310 | <p>You can define <a href="#groups">menu groups</a> by wrapping <code>item</code> elements in a <code>group</code> |
| 311 | element, and create Submenus by nesting another <code>menu</code> inside an <code>item</code>. |
| 312 | Each element also supports all the necessary attributes to control features like shortcut keys, |
| 313 | checkboxes, icons, and more. To learn about these attributes and more about the XML syntax, see the Menus |
| 314 | topic in the <a href="{@docRoot}guide/topics/resources/available-resources.html#menus">Available |
| 315 | Resource Types</a> document.</p> |
| 316 | |
| 317 | <h2 id="features">Menu Features</h2> |
| 318 | <p>Here are some other features that can be applied to most menu items.</p> |
| 319 | |
| 320 | <h3 id="groups">Menu groups</h3> |
| 321 | <p>When adding new items to a menu, you can optionally include each item in a group. |
| 322 | A menu group is a collection of menu items that can share certain traits, like |
| 323 | whether they are visible, enabled, or checkable.</p> |
| 324 | |
| 325 | <p>A group is defined by an integer (or a resource id, in XML). A menu item is added to the group when it is |
| 326 | added to the menu, using one of the <code>add()</code> methods that accepts a <var>groupId</var> |
| 327 | as an argument, such as <code>{@link android.view.Menu#add(int,int,int,int)}</code>.</p> |
| 328 | |
| 329 | <p>You can show or hide the entire group with |
| 330 | <code>{@link android.view.Menu#setGroupVisible(int,boolean) setGroupVisible()}</code>; |
| 331 | enable or disable the group with |
| 332 | <code>{@link android.view.Menu#setGroupEnabled(int,boolean) setGroupEnabled()}</code>; |
| 333 | and set whether the items can be checkable with |
| 334 | <code>{@link android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}</code>. |
| 335 | </p> |
| 336 | |
| 337 | <h3 id="checkable">Checkable menu items</h3> |
| 338 | <img align="right" src="{@docRoot}images/radio_buttons.png" alt="" /> |
| 339 | <p>Any menu item can be used as an interface for turning options on and off. This can |
| 340 | be indicated with a checkbox for stand-alone options, or radio buttons for groups of |
Elliott Hughes | 7f87706 | 2009-07-30 17:00:34 -0700 | [diff] [blame^] | 341 | mutually exclusive options (see the screenshot, to the right).</p> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 342 | |
| 343 | <p class="note"><strong>Note:</strong> Menu items in the Icon Menu cannot |
| 344 | display a checkbox or radio button. If you choose to make items in the Icon Menu checkable, |
| 345 | then you must personally indicate the state by swapping the icon and/or text |
| 346 | each time the state changes between on and off.</p> |
| 347 | |
| 348 | <p>To make a single item checkable, use the <code>{@link android.view.MenuItem#setCheckable(boolean) |
| 349 | setCheckable()}</code> method, like so:</p> |
| 350 | <pre> |
| 351 | menu.add(0, VIBRATE_SETTING_ID, 0, "Vibrate") |
| 352 | .setCheckable(true); |
| 353 | </pre> |
| 354 | <p>This will display a checkbox with the menu item (unless it's in the Icon Menu). When the item |
| 355 | is selected, the <code>onOptionsItemSelected()</code> callback is called as usual. It is here that |
| 356 | you must set the state of the checkbox. You can query the current state of the item with |
| 357 | <code>{@link android.view.MenuItem#isChecked()}</code> and set the checked state with |
| 358 | <code>{@link android.view.MenuItem#setChecked(boolean) setChecked()}</code>. |
| 359 | Here's what this looks like inside the |
| 360 | <code>onOptionsItemSelected()</code> callback:</p> |
| 361 | <pre> |
| 362 | switch (item.getItemId()) { |
| 363 | case VIBRATE_SETTING_ID: |
| 364 | if (item.isChecked()) item.setChecked(false); |
| 365 | else item.setChecked(true); |
| 366 | return true; |
| 367 | ... |
| 368 | } |
| 369 | </pre> |
| 370 | |
| 371 | <p>To make a group of mutually exclusive radio button items, simply |
| 372 | assign the same group ID to each menu item |
| 373 | and call <code>{@link android.view.Menu#setGroupCheckable(int,boolean,boolean) |
| 374 | setGroupCheckable()}</code>. In this case, you don't need to call <code>setCheckable()</code> |
| 375 | on each menu items, because the group as a whole is set checkable. Here's an example of |
| 376 | two mutually exclusive options in a Submenu:</p> |
| 377 | <pre> |
| 378 | SubMenu subMenu = menu.addSubMenu("Color"); |
| 379 | subMenu.add(COLOR_MENU_GROUP, COLOR_RED_ID, 0, "Red"); |
| 380 | subMenu.add(COLOR_MENU_GROUP, COLOR_BLUE_ID, 0, "Blue"); |
| 381 | subMenu.setGroupCheckable(COLOR_MENU_GROUP, true, true); |
| 382 | </pre> |
| 383 | <p>In the <code>setGroupCheckable()</code> method, the first argument is the group ID |
| 384 | that we want to set checkable. The second argument is whether we want the group items |
| 385 | to be checkable. The last one is whether we want each item to be exclusively checkable |
| 386 | (if we set this <em>false</em>, then all the items will be checkboxes instead of radio buttons). |
| 387 | When the group is set to be exclusive (radio buttons), each time a new item is selected, |
| 388 | all other are automatically de-selected.</p> |
| 389 | <p> |
| 390 | |
| 391 | <p class="note"><strong>Note:</strong> |
| 392 | Checkable menu items are intended to be used only on a per-session basis and not saved to the device |
| 393 | (e.g., the <em>Map mode</em> setting in the Maps application is not saved — screenshot above). |
| 394 | If there are application settings that you would like to save for the user, |
| 395 | then you should store the data using <a href="#{@docRoot}guide/topics/data/data-storage.html#pref">Preferences</a>, |
| 396 | and manage them with a {@link android.preference.PreferenceActivity}.</p> |
| 397 | |
| 398 | |
| 399 | <h3 id="shortcuts">Shortcut keys</h3> |
| 400 | <p>Quick access shortcut keys using letters and/or numbers can be added to menu items with |
| 401 | <code>setAlphabeticShortcut(char)</code> (to set char shortcut), <code>setNumericShortcut(int)</code> |
| 402 | (to set numeric shortcut), |
| 403 | or <code>setShortcut(char,int)</code> (to set both)</code>. Case is <em>not</em> sensitive. |
| 404 | |
| 405 | For example:</p> |
| 406 | <pre> |
| 407 | menu.add(0, MENU_QUIT, 0, "Quit") |
| 408 | .setAlphabeticShortcut('q'); |
| 409 | </pre> |
| 410 | <p>Now, when the menu is open (or while holding the MENU key), pressing the "q" key will |
| 411 | select this item.</p> |
| 412 | <p>This shortcut key will be displayed as a tip in the menu item, below the menu item name |
| 413 | (except for items in the Icon Menu).</p> |
| 414 | <p class="note"><strong>Note:</strong> Shortcuts cannot be added to items in a Context Menu.</p> |
| 415 | |
| 416 | |
| 417 | <h3 id="intents">Menu item intents</h3> |
| 418 | <p>If you've read the <a href="{@docRoot}guide/topics/fundamentals.html">Application |
| 419 | Fundamentals</a>, then you're at least a little familiar |
| 420 | with Android Intents. These allow applications to bind with each other, share information, |
| 421 | and perform user tasks cooperatively. Just like your application might fire an Intent to launch a web browser, |
| 422 | an email client, or another Activity in your application, |
| 423 | you can perform such actions from within a menu. |
| 424 | There are two ways to do this: define an Intent and assign it to a single menu item, or |
| 425 | define an Intent and allow Android to search the device for activities and dynamically add a |
| 426 | menu item for each one that meets the Intent criteria.</p> |
| 427 | |
| 428 | <p>For more information on creating Intents and providing your application's services to other applications, |
| 429 | read the <a href="/guide/topics/intents/intents-filters.html">Intents |
| 430 | and Intent Filters</a> document.</p> |
| 431 | |
| 432 | <h4>Set an intent for a single menu item</h4> |
| 433 | <p>If you want to offer a specific menu item that launches a new Activity, then you |
| 434 | can specifically define an Intent for the menu item with the |
| 435 | <code>{@link android.view.MenuItem#setIntent(Intent) |
| 436 | setIntent()}</code> method.</p> |
| 437 | |
| 438 | <p>For example, inside the <code>{@link android.app.Activity#onCreateOptionsMenu(Menu) |
| 439 | onCreateOptionsMenu()}</code> method, you can define a new menu item with an Intent like this:</p> |
| 440 | <pre> |
| 441 | MenuItem menuItem = menu.add(0, PHOTO_PICKER_ID, 0, "Select Photo"); |
| 442 | menuItem.setIntent(new Intent(this, PhotoPicker.class)); |
| 443 | </pre> |
| 444 | <p>Android will automatically launch the Activity when the item is selected.</p> |
| 445 | |
| 446 | <p class="note"><strong>Note:</strong> This will not return a result to your Activity. |
| 447 | If you wish to be returned a result, then do not use <code>setIntent()</code>. |
| 448 | Instead, handle the selection as usual in the <code>onOptionsMenuItemSelected()</code> |
| 449 | or <code>onContextMenuItemSelected()</code> callback and call |
| 450 | <code>{@link android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()}</code>. |
| 451 | </p> |
| 452 | |
| 453 | <h4>Dynamically add intents</h4> |
| 454 | |
| 455 | <p>If there are potentially multiple activities that are relevant to your current |
| 456 | Activity or selected item, then the application can dynamically add menu items that execute other |
| 457 | services.</p> |
| 458 | <p>During menu creation, define an Intent with the category <var>Intent.ALTERNATIVE_CATEGORY</var> and/or |
| 459 | <var>Intent.SELECTED_ALTERNATIVE</var>, the MIME type currently selected (if any), and any other |
| 460 | requirements, the same way as you would satisfy an intent filter to open a new |
| 461 | Activity. Then call |
| 462 | <code>{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) |
| 463 | addIntentOptions()}</code> to have Android search for any services meeting those requirements |
| 464 | and add them to the menu for you. If there are no applications installed |
| 465 | that satisfy the Intent, then no additional menu items are added.</p> |
| 466 | |
| 467 | <p class="note"><strong>Note:</strong> |
| 468 | <var>SELECTED_ALTERNATIVE</var> is used to handle the currently selected element on the |
| 469 | screen. So, it should only be used when creating a Menu in <code>onCreateContextMenu()</code> or |
| 470 | <code>onPrepareOptionsMenu()</code>, which is called every time the Options Menu is opened.</p> |
| 471 | |
| 472 | <p>Here's an example demonstrating how an application would search for |
| 473 | additional services to display on its menu.</p> |
| 474 | |
| 475 | <pre> |
| 476 | public boolean onCreateOptionsMenu(Menu menu){ |
| 477 | super.onCreateOptionsMenu(menu); |
| 478 | |
| 479 | // Create an Intent that describes the requirements to fulfill, to be included |
| 480 | // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE. |
| 481 | Intent intent = new Intent(null, getIntent().getData()); |
| 482 | intent.addCategory(Intent.CATEGORY_ALTERNATIVE); |
| 483 | |
| 484 | // Search for, and populate the menu with, acceptable offering applications. |
| 485 | menu.addIntentOptions( |
| 486 | thisClass.INTENT_OPTIONS, // Menu group |
| 487 | 0, // Unique item ID (none) |
| 488 | 0, // Order for the items (none) |
| 489 | this.getComponentName(), // The current Activity name |
| 490 | null, // Specific items to place first (none) |
| 491 | intent, // Intent created above that describes our requirements |
| 492 | 0, // Additional flags to control items (none) |
Elliott Hughes | 7f87706 | 2009-07-30 17:00:34 -0700 | [diff] [blame^] | 493 | null); // Array of MenuItems that correlate to specific items (none) |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 494 | |
| 495 | return true; |
| 496 | }</pre> |
| 497 | |
| 498 | <p>For each Activity found that provides an Intent Filter matching the Intent defined, a menu |
| 499 | item will be added, using the <var>android:label</var> value of the intent filter as the text |
| 500 | for the menu item. |
| 501 | The <code>{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) addIntentOptions()}</code> method will also return the number of menu items added.</p> |
| 502 | <p>Also be aware that, when <code>addIntentOptions()</code> is called, it will override any and all |
| 503 | menu items in the menu group specified in the first argument.</p> |
| 504 | |
| 505 | <p>If you wish to offer the services of your Activity to other application menus, then you |
| 506 | only need to define an intent filter as usual. Just be sure to include the <var>ALTERNATIVE</var> and/or |
| 507 | <var>SELECTED_ALTERNATIVE</var> values in the <var>name</var> attribute of |
| 508 | a <code><category></code> element in the intent filter. For example:</p> |
| 509 | <pre> |
| 510 | <intent-filter label="Resize Image"> |
| 511 | ... |
| 512 | <category android:name="android.intent.category.ALTERNATIVE" /> |
| 513 | <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> |
| 514 | ... |
| 515 | </intent-filter> |
| 516 | </pre> |
| 517 | <p>read more about writing intent filters in the |
| 518 | <a href="/guide/topics/intents/intents-filters.html">Intents and Intent Filters</a> document.</p> |
| 519 | |
| 520 | <p>For a sample application using this technique, see the |
| 521 | <a href="{@docRoot}guide/samples/NotePad/index.html">Note Pad</a> |
| 522 | sample code.</p> |