理解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

 

子菜单提供了一种自然的组织菜单项的方式,它被大量地运用在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中可以为子菜单添加图标,但是不会显示其菜单项的图标,这一点需要留意。除了代码中的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(安卓)的网络编程(17)-android显示网络图片
  3. [原]如何在Android用FFmpeg+SDL2.0解码显示图像
  4. 『ANDROID』android:layout_gravity和android:gravity属性的区别
  5. Android(安卓)面试题总结之Android(安卓)基础(五)
  6. 【Android(安卓)TextView/EditText 不允许换行】android:lines
  7. iPhone和Android(安卓)UI模式比较列表
  8. android弹力效果菜单、组件化项目、电影选座控件的源码
  9. android实现密码框右侧显示小眼睛

随机推荐

  1. Android实现拖拽GridView到目标View
  2. android studio 修改包名
  3. android Preference Demo
  4. Android IjkPlayer 视频播放器
  5. Android AlertDialog工具类 实现对话框回
  6. Android之调用js常见错误
  7. Attacking memory problems on Android
  8. How to enable Android ConfigFS gadgets
  9. Android 图片的缓存机制分析
  10. Android/OPhone中使用HttpUrlConnection