4.5 Menu和ActionBar
菜单是人机交互的重要接口,在Android SDK中,提供了菜单类android.view.Menu,以完成与菜单有关的操作。
Android SDK提供三种菜单,分别如下。
• Options Menu:选项菜单,是Activity的主要菜单项的集合,当用户单击Menu按钮时出现。在Android 2.3以下的版本中,这种菜单最多显示6个带图标的菜单项。当菜单中含有6个以上的菜单项时,弹出菜单将只显示前5个菜单项,第6个菜单项会变为More,单击More菜单项后会出现扩展菜单。扩展菜单不支持图标,但支持单选框和复选框。在Android 3.0(API Level 11)及以上版本中,默认情况下直接弹出的选项菜单不再显示图标。
• Context Menu:上下文菜单,是一个悬浮的菜单项列表,当用户单击注册了上下文菜单的组件时出现。上下文菜单不支持菜单图标和快捷键。
• Submenu:子菜单,是某个菜单项的扩展,是一个悬浮的菜单项列表。子菜单不支持菜单图标或者嵌套子菜单。
4.5.1 Options Menu
要实现选项菜单的功能,首先需要重载OnCreatOptionsMenu()方法创建菜单,然后通过onOptionsItemSelected()方法对菜单被单击事件进行监听和处理。
创建一个名为MenusDemo的Android Project,在该工程中对菜单的相关知识进行学习。
在工程的res目录下创建一个menu目录,用于存放菜单相关的XML文件。在该目录下创建mymenu.xml,代码如下:
mymenu.xml创建了一个具有7个菜单项的菜单,并且通过android:id属性为每个菜单项指定ID,通过android:title属性为每个菜单项指定显示的菜单项内容,通过android:icon属性指定每个菜单项的图标。对应的图标文件放置到res/drawable目录下。
为工程MenusDemo创建名为MenusActivity的Activity,将mymenu.xml中定义的菜单设置为MenusActivity的菜单,重载OnCreatOptionsMenu()方法。MenusActivity.java的代码如下:
其中:
这几行代码通过MenuInflater. Inflate()方法将menu.xml中定义的菜单项内容填充到了菜单中。
在OnCreatOptionsMenu()方法中创建菜单时也支持Menu.add()方法,也能达到同样目的,例如:
menu.add(0,itemid,0,item_title);
表示在菜单中添加一个菜单项,该菜单项的ID为itemid,菜单项显示的内容为item_title的内容。但是不鼓励使用这种方式,而应该使用XML文件来创建菜单。
运行MenusDemo实例,单击手机的Menu按钮,得到的效果如图4.35所示。
图4.35 “Menu”按钮运行效果
由运行效果可见,MenusActivity已经根据mymenu.xml文件创建了一个具有7个菜单项的菜单。但是虽然在mymenu.xml文件中为每个菜单项指定了一个图标,但是生成的选项菜单中却并没有图标被显示出来,这是为什么呢?
实例MenusDemo当前的运行环境是Android 4.0,其API Level为14。我们先看一下,同样的代码,在API Level 11之前的运行效果。
双击打开AndroidManifest.xml文件,将其中的代码:
<uses-sdk android:minSdkVersion="14" />
改为:
<uses-sdk android:minSdkVersion="9" />
再次运行MenusDemo实例,单击Menu按钮,得到的效果如图4.36所示。
图4.36 API Level 11之前Menu按钮的运行效果
可见运行在早期的API之上的选项菜单效果要更好一些。为什么会出现这种现象呢?其实在Android SDK 3.0之后,就不再鼓励直接使用选项菜单,而是将选项菜单和ActionBar结合使用。
ActionBar又称活动栏,位于Activity的顶部,取代了原来标题的位置。ActionBar中包含很多ActionItem,相当于选项菜单的菜单项。将选项菜单与ActionBar结合的方法很简单,只要在XML文件中添加一个android:showAsAction="ifRoom"属性即可。该属性表现如果标题栏有空间的话,就将相关的菜单项放置到ActionBar中。如果标题栏空间不足,未能放置到其中的菜单项仍然会以选项菜单的形式出现。ActionBar的运行效果如图4.37所示。
图4.37 ActionBar的运行效果
4.5.2 Context Menu
上下文菜单注册到View对象上后,用户长按该View对象可呼出上下文菜单。上下文菜单悬浮于主界面之上,不支持图标显示和快捷键。其使用方法和选项菜单高度相似,只不过创建上下文菜单的方法为onCreateContextMenu(),响应上下文菜单单击事件的方法为onContextItemSelected()。
仍以工程MenusDemo为例,为MenusActivity的视图中的TextView对象添加一个具有两个菜单项的上下文菜单,运行效果如图4.38所示。
图4.38 两个上下文菜单的运行结果
为TextView对象注册上下文菜单的代码如下:
textview=(TextView)findViewById(R.id.textview1); registerForContextMenu(textview);
创建并处理上下文菜单单击事件的代码如下:
4.5.3 SubMenu
子菜单可以被添加到其他菜单上,但是子菜单本身不能再有子菜单。使用addSubMenu()方法为MenusActivity的选项菜单添加一个子菜单,运行效果如图4.39所示。
图4.39 添加子菜单的运行效果
实现该子菜单需要重写onCreateOptionsMenu()方法,代码如下:
子菜单的事件处理代码在onOptionsItemSelected()中实现。
MenusActivity.java的完整代码如下: