《Android Dev Guide》系列教程11:用户界面之Menu菜单特性
菜单特性
这里有一些大多数菜单项都有的特性
菜单组
当我们添加新的条目到一个菜单中,你可以让所有条目包含在一个组中,菜单组是菜单条目的集合,里面的菜单那项可以共享某些特性,比如是否可见、可用、可选。
一个菜单组被定义为整形(或者在xml中配置一个资源id),往menu中使用add()方法添加菜单项时,如果参数中包含了菜单组的id,那么这个条目会添加到相应的菜单组中。比如add(int,int,int,int)。使用setGroupVisible()方法可以设置整个组是否隐藏。setGroupEnabled()发那个发设置整个组是否可用,setGroupCheckable()设置整个组是否可选。
可选菜单项
任何菜单项都有是否可选的接口。可以是一个独立的选择框、单选框、单选按钮复选框,参考上面截图。
注意:在Icon菜单中,菜单项不能显示为但则狂或者单选按钮。如果你想在icon菜单中让条目可选,必须自己在状态改变时改变条目的现实。
想让一个条目可选,可以使用setCheckable()方法,像这样。
menu.add(0, VIBRATE_SETTING_ID,0,"Vibrate")
.setCheckable(true);
这样会显示一个选择框(前提是他不是一个icon菜单),当条目被选中时,onOptionsItemSelected()回调方法会被调用。这里你必须设置选择框的状态,你可以使用isChecked()查询当前状态或者使用setChecked()方法设置状态。类似于onOptionsItemsSelected()方法。
switch(item.getItemId()) {
caseVIBRATE_SETTING_ID:
if(item.isChecked()) item.setChecked(false);
elseitem.setChecked(true);
returntrue;
...
}
如果想让几个radio选择按钮成为一个单选按钮组,可以设置相同的groupId,然后调用setGroupCheckable()方法即可。这种情况下,不用每个item都调用setCheckable()方法,下面是一个子菜单中的两个单选按钮组:
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);
在setGroupCheckable()方法中,第一个参数为要设置的groupId,第二个为菜单项是否可选,最后一个参数是是否为单选(设为false的则所有item选择情况相互独立,即可以多选),当group设为单选时,每一次有条目被选中时,其他选项自动设置为未选状态(即单选)。
注意:可选菜单按钮是基于会话的,其状态、结果并不会保存在设备上。如截图所示:在地图程序中的设置并不会保存。如果你想把设置的记过保存,可以使用Preferences累,并且使用PreferencesActivity类来管理他们。
Shortcut keys
使用setAlphabeticShortcut(char)方法,可以给菜单项中添加快捷键,使用setNumericShortcut(int)可以设置数字快捷键,或者使用setShortCut(char,int)。大小写不敏感,例如:
menu.add(0, MENU_QUIT,0,"Quit")
.setAlphabeticShortcut('q');
现在,当菜单打开时,或者按下menu键时,按下q键将会选择这个条目。
这个快捷键会当成菜单项的一个小提示来显示,在菜单项标签的下面(icon菜单除外)。
注意:快捷键不能加载Context菜单中。
菜单项的intents
如果你阅读了以前的章节,你会对Android Intents有所熟悉,它允许应用程序绑定到其他程序上,共享信息,各个任务间通信。就像你的程序可以启动一个web浏览器、或者email客户端或者其他的activity,你可以在一个菜单中运行它们。有两种方式:为每个菜单项定义一个intent;或者定义intent然后允许Android自动搜索activity,并为每个符合条件的activity添加菜单项。
关于建立intents和为程序提供服务的详细信息,可以参考Intents and Intent Filter 章节
为单独的菜单项设置intent
如果你想让一个菜单项运行一个新的activity,那么你需要调用菜单项的setIntent()方发来定义intent。
例如,在onCreateOptionMenu()里,你可以这样定义:
MenuItem menuItem = menu.add(0, PHOTO_PICKER_ID,0,"Select Photo");
menuItem.setIntent(newIntent(this, PhotoPicker.class));
当点击菜单项时,android 会自动运行设置好的activity。
注意:这种运行方式不会返回数据,如果你想得到返回数据,那么不能使用setIntent()方法。你应该在onOptionsMenuItemSelected()方法或onContextMenuItemSelected()方法中调用startActivityForResult()方法。
动态添加intents
当前程序或者当前选项有可能会关联很多的activity,所以程序便可以动态的添加菜单项来执行那些操作。
在创建menu菜单时,根据当前选定项的MIME类型,来使用Intent.ALTERNATIVE_CATEGORY或者Intent.SELECTED_ALTERNATIVE这两个参数来设置intent的分类,或者其他的参数来让intent filter (intent过滤器)启动一个新的acticity。然后调用addIntentOptions()来让android搜索到符合要求的服务并且添加到menu菜单中。如果没有合适的相应程序则菜单不添加条目。
注意:SELECTED_ALTERNATIVE 处理当前屏幕里选中项,所以,之有当在onCreateContextMenu()方法和onPrepareOptionsMenu()方法里建立菜单时时才能使用。
下面的例子,展示了程序怎样找到额外的服务来显示到菜单中。
publicbooleanonCreateOptionsMenu(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 = newIntent(null, getIntent().getData());
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
// Search for, and populate the menu with, acceptable offering applications.
menu.addIntentOptions(
thisClass.INTENT_OPTIONS, // Menu group
0,// Unique item ID (none)
0,// Order for the items (none)
this.getComponentName(),// The current Activity name
null,// Specific items to place first (none)
intent, // Intent created above that describes our requirements
0,// Additional flags to control items (none)
null);// Array of MenuItems that correlate to specific items (none)
returntrue;
}
当activity发现有合适的intent过滤器时,便会添加一个相应的menu菜单项,菜单项会显示lable标签的内容。addIntentOptions()方法会返回添加的菜单项的个数。
必须注意:当addIntentOptions()方法被调用时,他将会覆盖第一个参数所指定菜单里的所有项。
如果你想为其他菜单提供服务,你只需要定义一个intent filter,只要再标签里包含 ALTERNATIVE 或者 SELECTED_ALTERNATIVE 即可,例如:
...
...