理解Android的菜单

菜单是许多应用程序不可或缺的一部分,Android中更是如此,所有搭载Android系统的手机甚至都要有一个"Menu"键,由此可见菜单在Android程序中的特殊性。Android SDK提供的菜单有如下几种:

  1. 选项菜单:最常规的菜单,android中把它叫做option menu
  2. 子菜单:android中点击子菜单将弹出悬浮窗口显示子菜单项。子菜单不支持嵌套,即子菜单中不能再包括其他子菜单。
  3. 上下文菜单:android中长按视图控件后出现的菜单,windows点击右键弹出的菜单即上下文菜单
  4. 图标菜单:这个比较简单,就是带icon的菜单项,需要注意的是子菜单项、上下文菜单项、扩展菜单项均无法显示图标
  5. 选择菜单(alternative menu):用的比较少。
  6. 扩展菜单:选项菜单最多只能显示6个菜单项,超过6个时,第6个菜单项会被系统替换为一个叫“更多”的子菜单,原来显示不下的菜单项都作为“更多”菜单的子菜单项。

ContextMenu简介

android是通过长按某个视图元素来弹出上下文菜单的android的context menu上下文菜单,选择某项VIEW后长按menu键,就会显示出来。  SDK上的描述:Context Menu A floating list of menu items that appears when the user performs a long-press on a View.

使用步骤(使用XML生成菜单)

    

   1.在activity的onCreate(...)方法中为一个view注册上下文菜单

   2.在onCreateContextMenuInfo(...)中生成上下文菜单。

   3.在onContextItemSelected(...)中响应上下文菜单项。

  ContextMenu的使用也比较简单和OptionsMenu相似,先添加XML文件,然后重载对应的方法成员。   首先在res文件夹下新建menu目录,然后往里面添加menu的XML 文件。OptionsMenu  和 ContextMenu格式的是一样的。 < menu  xmlns:android ="http://schemas.android.com/apk/res/android" >
< item  android:id ="@+id/deleteTeam"  android:title ="@string/delete"
android:icon
="@android:drawable/ic_menu_delete" />
menu >

 

  item:每一个item对应一项菜单。   android:icon:用于指定菜单显示的图标。   android:title:菜单的标题,显示在图标下面。   关于Menu的更多属性设置请查看SDK上的  Menu Resource。   第二步是重写  onCreateContextMenu方法。 复制代码 代码 @Override
public void  onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {

super .onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater
= getMenuInflater();
inflater.inflate(R.menu.meetings_context_menu, menu);
}
复制代码

 

接下来是处理菜单的点击事件   复制代码 代码 @Override
public  boolean  onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info 
=  (AdapterContextMenuInfo) item.getMenuInfo();
switch  (item.getItemId()) {
  case  R.id.delete_meeting:
    postionOfMeetingToDelete 
=  info.position;
    showDialog(CONFIRM_DELETE_MEETING_DIALOG);
    return  true ;
  default :
    return  super .onContextItemSelected(item);
  }
}
复制代码

 

这里我们使用 AdapterContextMenuInfo 来获取上下文菜单 获取对应VIEW 的信息。.position 在这里返回了ListActivity中的位置,   The position in the adapter for which the context menu is being displayed.

注册菜单

  ContextMenu和OptionsMenu主菜单不同的是上下文菜单需要使用registerForContextMenu进行注册,否则将无法显示。 复制代码 代码 @Override
protected  void  onCreate(Bundle savedInstanceState) {
    super .onCreate(savedInstanceState);
    setContentView(R.layout.teams);
    // 将右键菜单注册给List 控件
    registerForContextMenu(getListView());
}
复制代码   

创建options menu

之前提到,Android的activity已经为我们提前创建好了android.view.Menu对象,并提供了回调方法onCreateOptionsMenu(Menu menu)供我们初始化菜单的内容。该方法只会在选项菜单第一次显示的时候被执行,如果你需要动态改变选项菜单的内容,请使用 onPrepareOptionsMenu(Menu)

 

复制代码
@Override
publicboolean onCreateOptionsMenu(Menu menu) {
// 调用父类方法来加入系统菜单
// 虽然目前android还没有系统菜单,但是为了兼容到以后的版本,最好加上
super.onCreateOptionsMenu(menu);

// 添加菜单项(多种方式)
// 1.直接指定标题
menu.add("菜单项1");
// 2.通过资源指定标题
menu.add(R.string.menuitem2);
// 3.显示指定菜单项的组号、ID、排序号、标题
menu.add(
1, //组号
Menu.FIRST, //唯一的ID号
Menu.FIRST, //排序号
"菜单项3"); //标题

// 如果希望显示菜单,请返回true
returntrue;
}
复制代码


上面的代码演示了添加菜单项的3种方法,下面解释下第三种方法
add(int groupId, int itemId, int order, CharSequence title)。其中,第一个参数是组号,android中你可以给菜单分组,以便快速地操作同一组的菜单。第二个参数指定每个菜单项的唯一ID号,你可以自己指定,也可以让系统来自动分配,在响应菜单时你需要通过ID号来判断哪个菜单被点击了。因此常规的做法是定义一些ID常量,但在android中有更好的方法,就是通过资源文件来引用,这个之后介绍。第三个参数代表菜单项显示顺序的编号,编号小的显示在前面。

给菜单项分组

复制代码
@Override
publicboolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// 添加4个菜单项,分成2组
int group1 =1;
int gourp2 =2;
menu.add(group1,
1, 1, "item 1");
menu.add(group1,
2, 2, "item 2");
menu.add(gourp2,
3, 3, "item 3");
menu.add(gourp2,
4, 4, "item 4");
// 显示菜单
returntrue;
}
复制代码

 

你可以向上面这样给菜单项分组,分组之后就能使用menu中提供的方法对组进行操作了,如下:

 

menu.removeGroup(group1);    //删除一组菜单
menu.setGroupVisible(gourp2, visible); //设置一组菜单是否可见
menu.setGroupEnabled(gourp2, enabled); //设置一组菜单是否可点
menu.setGroupCheckable(gourp2, checkable, exclusive); //设置一组菜单的勾选情况

 

响应菜单项

android提供了多种响应菜单项的方式,下面一一介绍

1、通过onOptionsItemSelected方法

使用的最多方法是重写activity类的 onOptionsItemSelected(MenuItem)回调方法,每当有菜单项被点击时,android就会调用该方法,并传入被点击菜单项。

 

复制代码
@Override
publicboolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//响应每个菜单项(通过菜单项的ID)
case1:
// do something here
break;
case2:
// do something here
break;
case3:
// do something here
break;
case4:
// do something here
break;
default:
//对没有处理的事件,交给父类来处理
returnsuper.onOptionsItemSelected(item);
}
//返回true表示处理完菜单项的事件,不需要将该事件继续传播下去了
returntrue;
}
复制代码

 

以上代码可作为使用onOptionsItemSelected方法响应菜单的模板来使用,这里为了方便起见将菜单ID硬编码在程序里,你可以使用常量或资源ID来使代码更健壮。

2.使用监听器

虽然第一种方法是推荐使用的方法,android还是提供了类似java swing的监听器方式来响应菜单。使用监听器的方式分为两步:

 

复制代码
//第一步:创建监听器类
class MyMenuItemClickListener implements OnMenuItemClickListener {
@Override
publicboolean onMenuItemClick(MenuItem item) {
// do something here...
returntrue; //finish handling
}
}

//第二步:为菜单项注册监听器
menuItem.setOnMenuItemClickListener(new MyMenuItemClickListener());
复制代码

 

android文档对onMenuItemClick(MenuItem item)回调方法的说明是"Called when a menu item has been invoked. This is the first code that is executed; if it returns true, no other callbacks will be executed." 可见该方法先于onOptionsItemSelected执行

3.使用Intent响应菜单

第3种方式是直接在MenuItem上调用setIntent(Intent intent)方法,这样android会自动在该菜单被点击时调用 startActivity(Intent)。但是个人认为与其这样还不如直接在onOptionsItemSelected的case里手动调用 startActivity(Intent)来的直观。

子菜单Sub Menu

android之Menu_第1张图片 

子菜单提供了一种自然的组织菜单项的方式,它被大量地运用在windows和其他OS的GUI设计中。Android同样支持子菜单,你可以通过addSubMenu(int groupId, int itemId, int order, int titleRes)方法非常方便的创建和响应子菜单。

复制代码
@Override
publicboolean onCreateOptionsMenu(Menu menu) {
int base = Menu.FIRST;
// 一个menu可以包括多个子菜单
SubMenu subMenu = menu.addSubMenu(base, base+1, Menu.NONE, "系统设置");
// 子菜单可以包括多个菜单项
MenuItem menuitem1 = subMenu.add(base, base+1, base+1, "显示设置");
subMenu.add(base, base
+2, base+2, "网络设置");
subMenu.add(base, base
+3, base+3, "高级设置");
subMenu.add(base, base
+4, base+4, "安全设置");

// 子菜单项不支持显示图标,这样做是没意义的,尽管不会报错!
menuitem1.setIcon(R.drawable.displaysettings);

//但是子菜单本身是支持图标的
subMenu.setIcon(R.drawable.settings);

// 显示菜单请返回true
returntrue;
}
复制代码

android之Menu_第2张图片 android之Menu_第3张图片 android之Menu_第4张图片

上面的代码演示了如何创建子菜单,其菜单项的响应其实就是普通菜单项的响应,上一篇已经作了详细介绍,这里不再赘述。Android中可以为子菜单添加图标,但是不会显示其菜单项的图标,这一点需要留意。除了代码中的setIcon(int iconRes)方法,还有一个setHeaderIcon(int iconRes)方法可以添加子菜单项栏目的标题图标,效果如上面第三张图。

最后需要强调的是,Menu可以包含多个SubMenu,SubMenu可以包含多个MenuItem(这三者之间的关系见Android菜单详解(一)——理解Android中的Menu),但是SubMenu不能包含SubMenu,及子菜单不能嵌套!!!下面的代码能通过编译,但会在运行时出错。

subMenu.addSubMenu("又一个子菜单");

图标菜单Icon Menu

Android支持在菜单上显示各种各样的图标,这一点我们在上面创建子菜单时已经用到了。图标菜单严格上说并不算是一种菜单的新类型,它的使用也很简单,之所以单独设一节是为了说明使用Icon的一些限制。Android中并不是所谓的菜单项都能加上图标,以下菜单项都是不可以的(这并不意味着程序会报错,而是运行时图标得不到显示):

  • 扩展的菜单项。如果不理解什么是扩展的菜单,可以参考Android菜单详解(一)——理解Android中的Menu
  • 子菜单的菜单项
  • 上下文菜单的菜单项

除此以外,带Icon的菜单项不能加上复选框(check mark)。总之,虽然精美的图标能给我们的应用增色不少,但是滥用图标也是会适得其反的,Android SDK给图标菜单加的这些限制也算是有效的防止我们滥用图标了吧。








更多相关文章

  1. Android菜单详解(一)——理解Android中的Menu
  2. android弹力效果菜单、组件化项目、电影选座控件的源码
  3. android 代码proguard
  4. Android日志系统分析之日志设备驱动程序代码阅读
  5. Android Material Design: NavigationView抽屉导航菜单
  6. android 为activity添加optionMenu选项菜单
  7. Android Studio实现代码混淆
  8. Android之打开闪光灯关键代码

随机推荐

  1. Android(安卓)Coding: Gestures Builder:
  2. android RN 配置和打包命令
  3. Android获取手机方向
  4. Android(安卓)监听EditText文本输入 Edit
  5. 什么是Dalvik【摘】
  6. Android(安卓).9图片使用报错...报错:AAP
  7. Android(安卓)Transition(Android过渡动画
  8. android 获取.thumbnail文件下的小图标
  9. Android——NDK下载提示缺少toolchains问
  10. Android--用Pull解析器将对象解析成xml文