In concord with Android's philosophy of separating appearance from function, menus are generally created in the same way as other visual elements, that is, with the use of a definitive XML layout file.
There is a lot that can be done to control menus dynamically and Android provides classes and interfaces for displaying context-sensitive menus, organizing menu items into groups, and including shortcuts.
To keep our application code separate from our menu layout information, Android uses a designated resource folder (res/menu) and an XML layout file to define the physical appearance of our menu; such as the titles and icons we see in Android pop-up menus. The Activity class contains a callback method, onCreateOptionsMenu(), that can be overridden to inflate a menu.
Android menus are defined in a specific, designated folder. Eclipse does not create this folder by default so start up a new project and add a new folder inside the res folder and call it menu.
<?xml version="1.0" encoding="utf-8"?>
<menu
>
<item
android_id="@+id/item_one"
android_title="first item" />
<item
android_id="@+id/item_two"
android_title="second item" />
</menu>
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.my_menu, menu);
return true;
}
Whenever we create an Android menu using XML we must place it in the folder we used here (res/menu). Likewise, the base node of our XML structure must be <menu>.
The purpose of the id element should be self explanatory and the title attribute is used to set the text that the user sees when the menu item is inflated.
The MenuInflater object is a straightforward way of turning an XML layout file into a Java object. We create a MenuInflater with getMenuInflater() which returns a MenuInflater from the current activity, of which it is a member. The inflate() call takes both the XML file and the equivalent Java object as its parameters.
The type of menu we created here is referred to as an options menu and it comes in two flavors depending on how many items it contains. There is also a neater way to handle item titles when they are too long to be completely displayed.
When an options menu has six or fewer items it appears as a block of items at the bottom of the screen. This is called the icon menu and is, as its name suggests, the only menu type capable of displaying icons. On tablets running API level 11 or greater the Action bar can also be used to access the menu.
The icon menu is also the only menu type that cannot display radio buttons or check marks.
When an inflated options menu has more than six items, the sixth place on the icon menu is replaced by the system's own More item, which when pressed calls up the extended menu which displays all items from the sixth onwards, adding a scroll bar if necessary.
If Android cannot fit an item's title text into the space provided (often as little as one third of the screen width) it will simply truncate it. To provide a more readable alternative, include the android:titleCondensed="string" attribute alongside android:title in the item definition.
For tablet devices targeting Android 3.0 or greater, option menu items can be added to the Action Bar.
Adjust the target build of the above project to API level 11 or above and replace the res/menu/my_menu.xml file with the following:
<?xml version="1.0" encoding="utf-8"?>
<menu
>
<item
android_id="@+id/item_one"
android_title="first item"
android_icon="@drawable/icon"
android_showAsAction="ifRoom" />
<item
android_id="@+id/item_two"
android_title="second item"
android_icon="@drawable/icon"
android_showAsAction="ifRoom|withText" />
<item
android_id="@+id/item_three"
android_title="third item"
android_icon="@drawable/icon"
android_showAsAction="always" />
<item
android_id="@+id/item_four"
android_title="fourth item"
android_icon="@drawable/icon"
android_showAsAction="never" />
</menu>
Note from the output that unless the withText flag is included, the menu item will display only as an icon:
The menu items we defined in the previous recipe had only text titles to identify them to the user, however nearly all Icon Menus that we see on Android devices combine a text title with an icon. Although it is perfectly possible to use any graphic image as a menu icon, using images that do not conform to Android's own guidelines on icon design is strongly discouraged, and Android's own development team are particularly insistent that only the subscribed color palette and effects are used. This is so that these built-in menus which are universal across Android applications provide a continuous experience for the user.
Here we examine the colors and dimensions prescribed and also examine how to provide the subsequent images as system resources in such a way as to cater for a variety of screen densities.
The little application we put together in the last recipe makes a good starting point for this one. Most of the information here is to do with design of the icons, so you may want to have a graphics editor such as GIMP or PhotoShop open, or you may want to refer back here later for the exact dimensions and palettes.
<?xml version="1.0" encoding="utf-8"?>
<menu
>
<item
android_id="@+id/item_one"
android_icon="@drawable/my_menu_icon"
android_title="first item" />
<item
android_id="@+id/item_two"
android_icon="@drawable/my_menu_icon"
android_title="second item" />
</menu>
As already mentioned, Android currently insists that menu icons conform to their guidelines and most of the terms used here should be familiar to anyone who has designed an icon before.
The designated drawable folders allow us to provide the best possible graphics for a wide variety of screen densities. Android will automatically select the most appropriate graphic for a handset or tablet so that we can refer to our icons generically with @drawable/.
It is only ever necessary to provide icons for the first five menu items as the Icon Menu is the only type to allow icons.