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

选项菜单:最常规的菜单,android中把它叫做option menu
子菜单:android中点击子菜单将弹出悬浮窗口显示子菜单项。子菜单不支持嵌套,即子菜单中不能再其他子菜单。
上下文菜单:android中长按视图控件后出现的菜单,windows点击右键弹出的菜单即上下文菜单
图标菜单:这个比较简单,就是带icon的菜单项,需要注意的是子菜单项、上下文菜单项、扩展菜单项均无法显示图标。
选择菜单(alternative menu):用的比较少,以后单独介绍,本文先跳过(其实是我还没弄明白啦o(≧v≦)o~~)
扩展菜单:选项菜单最多只能显示6个菜单项,超过6个时,第6个菜单项会被系统替换为一个叫“更多”的子菜单,原来显示不下的菜单项都作为“更多”菜单的子菜单项。如下图:

android.view.Menu接口代表一个菜单,android用它来管理各种菜单项。注意我们一般不自己创建menu,因为每个Activity 默认都自带了一个,我们要做的是为它加菜单项和响应菜单项的点击事件。android.view.MenuItem代表每个菜单 项,android.view.SubMenu代表子菜单。其三者的关系可以用下图来表示


上面说过,每个activity包含一个菜单,一个菜单又能包含多个菜单项和多个子菜单,子菜单其实也是菜单(因为它实现了Menu接口),因此子菜单也 可以包含多个菜单项。SubMenu继承了Menu的addSubMenu()方法,但调用时会抛出运行时错误。 OnCreateOptionsMenu()和OnOptionsMenuSelected()是activity中提供了两个回调方法,用于创建菜单项 和响应菜单项的点击。


我们看一下如何通过代码创建和响应最常用的选项菜单(options menu)。

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

java代码:

  1. @Override
  2. public boolean onCreateOptionsMenu(Menu menu) {
  3. // 调用父类方法来加入系统菜单
  4. // 虽然目前android还没有系统菜单,但是为了兼容到以后的版本,最好加上
  5. super.onCreateOptionsMenu(menu);
  6. // 添加菜单项(多种方式)
  7. // 1.直接指定标题
  8. menu.add("菜单项1");
  9. // 2.通过资源指定标题
  10. menu.add(R.string.menuitem2);
  11. // 3.显示指定菜单项的组号、ID、排序号、标题
  12. menu.add(
  13. 1, //组号
  14. Menu.FIRST, //唯一的ID号
  15. Menu.FIRST, //排序号
  16. "菜单项3"); //标题
  17. // 如果希望显示菜单,请返回true
  18. return true;
  19. }
复制代码


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

给菜单项分组

java代码:

  1. @Override
  2. public boolean onCreateOptionsMenu(Menu menu) {
  3. super.onCreateOptionsMenu(menu);
  4. // 添加4个菜单项,分成2组
  5. int group1 = 1;
  6. int gourp2 = 2;
  7. menu.add(group1, 1, 1, "item 1");
  8. menu.add(group1, 2, 2, "item 2");
  9. menu.add(gourp2, 3, 3, "item 3");
  10. menu.add(gourp2, 4, 4, "item 4");
  11. // 显示菜单
  12. return true;
  13. }
复制代码

第一个int类型的group ID参数,代表的是组概念,你可以将几个菜单项归为一组,以便更好的以组的方式管理你的菜单按钮。可以用到的方法有:
removeGroup(id)
setGroupCheckable(id, checkable, exclusive)
setGroupEnabled(id,boolean enabled)
setGroupVisible(id,visible)
个人认为,当你需要在不同场合下显示不同的menu的时候,合理使用这个参数将更为有效的处理菜单的显示。否则一般情况下都归为一组。
第二个int类型的item ID参数,代表的是项目编号。这个参数非常重要,一个item ID对应一个Menu中的选项。在后面使用菜单的时候,就是靠这个item ID来判断,你选中的是哪个选项。
第三个int类型的order ID参数,代表的是菜单项的显示顺序。默认是0,表示菜单的显示顺序就是按照add的顺序来显示。
第四个String类型的title参数,表示选项中显示的文字。

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

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


响应菜单项
android提供了多种响应菜单项的方式,下面一一介绍
1、通过onOptionsItemSelected方法

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

java代码:

  1. @Override
  2. public boolean onOptionsItemSelected(MenuItem item) {
  3. switch (item.getItemId()) {
  4. //响应每个菜单项(通过菜单项的ID)
  5. case 1:
  6. // do something here
  7. break;
  8. case 2:
  9. // do something here
  10. break;
  11. case 3:
  12. // do something here
  13. break;
  14. case 4:
  15. // do something here
  16. break;
  17. default:
  18. //对没有处理的事件,交给父类来处理
  19. return super.onOptionsItemSelected(item);
  20. }
  21. //返回true表示处理完菜单项的事件,不需要将该事件继续传播下去了
  22. return true;
  23. }
复制代码


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

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

java代码:

  1. //第一步:创建监听器类
  2. class MyMenuItemClickListener implements OnMenuItemClickListener {
  3. @Override
  4. public boolean onMenuItemClick(MenuItem item) {
  5. // do something here...
  6. return true; //finish handling
  7. }
  8. }
  9. //第二步:为菜单项注册监听器
  10. menuItem.setOnMenuItemClickListener(new MyMenuItemClickListener());
复制代码


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

本讲内容:菜单 menu
1、选项菜单 OptionsMenu
2、上下文菜单 ContextMenu
3、子菜单 SubMenu

组成Android用户界面的除了View以外,还有菜单和对话框,这一讲我们就共同学习一下菜单的使用。

菜单是用户界面中最常见的元素,使用也非常频繁,在Android中,菜单被分为如下三种,选项菜单(OptionsMenu)、上下文菜单(ContextMenu)和子菜单(SubMenu),下面分别举例说明。

一、选项菜单 OptionsMenu

Android手机上有个Menu按键,当Menu按下的时候,每个Activity都可以选择处理这一请求,在屏幕底部弹出一个菜单,这个菜单我 们就叫他选项菜单OptionsMenu,一般情况下,选项菜单最多显示2排每排3个菜单项,这些菜单项有文字有图标,也被称作Icon Menus,如果多于6项,从第六项开始会被隐藏,在第六项会出现一个More里,点击More才出现第六项以及以后的菜单项,这些菜单项也被称作 Expanded Menus。

下面我们通过一个例子来学习选项菜单,重要提示都放在代码注释里了,请留意一下。

1、新建一个项目 Lesson16_HelloMenu,主Activity叫 MainHelloMenu.java

2、res\layout\main.xml的内容如下:

<?xml version="1.0" encoding="utf-8"?>

3、MainHelloMenu.java的内容如下:

package android.basic.lesson16;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.Toast;public class MainHelloMenu extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);}// 点击Menu时,系统调用当前Activity的onCreateOptionsMenu方法,并传一个实现了一个Menu接口的menu对象供你使用@Overridepublic boolean onCreateOptionsMenu(Menu menu) {/* * add()方法的四个参数,依次是: * 1、组别,如果不分组的话就写Menu.NONE, * 2、Id,这个很重要,Android根据这个Id来确定不同的菜单 * 3、顺序,那个菜单现在在前面由这个参数的大小决定 * 4、文本,菜单的显示文本 */menu.add(Menu.NONE, Menu.FIRST + 1, 5, "删除").setIcon(android.R.drawable.ic_menu_delete);// setIcon()方法为菜单设置图标,这里使用的是系统自带的图标,同学们留意一下,以// android.R开头的资源是系统提供的,我们自己提供的资源是以R开头的menu.add(Menu.NONE, Menu.FIRST + 2, 2, "保存").setIcon(android.R.drawable.ic_menu_edit);menu.add(Menu.NONE, Menu.FIRST + 3, 6, "帮助").setIcon(android.R.drawable.ic_menu_help);menu.add(Menu.NONE, Menu.FIRST + 4, 1, "添加").setIcon(android.R.drawable.ic_menu_add);menu.add(Menu.NONE, Menu.FIRST + 5, 4, "详细").setIcon(android.R.drawable.ic_menu_info_details);menu.add(Menu.NONE, Menu.FIRST + 6, 3, "发送").setIcon(android.R.drawable.ic_menu_send);// return true才会起作用return true;}//菜单项被选择事件@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case Menu.FIRST + 1:Toast.makeText(this, "删除菜单被点击了", Toast.LENGTH_LONG).show();break;case Menu.FIRST + 2:Toast.makeText(this, "保存菜单被点击了", Toast.LENGTH_LONG).show();break;case Menu.FIRST + 3:Toast.makeText(this, "帮助菜单被点击了", Toast.LENGTH_LONG).show();break;case Menu.FIRST + 4:Toast.makeText(this, "添加菜单被点击了", Toast.LENGTH_LONG).show();break;case Menu.FIRST + 5:Toast.makeText(this, "详细菜单被点击了", Toast.LENGTH_LONG).show();break;case Menu.FIRST + 6:Toast.makeText(this, "发送菜单被点击了", Toast.LENGTH_LONG).show();break;}return false;}//选项菜单被关闭事件,菜单被关闭有三种情形,menu按钮被再次点击、back按钮被点击或者用户选择了某一个菜单项@Overridepublic void onOptionsMenuClosed(Menu menu){Toast.makeText(this, "选项菜单关闭了", Toast.LENGTH_LONG).show();}//菜单被显示之前的事件@Overridepublic boolean onPrepareOptionsMenu(Menu menu){Toast.makeText(this, "选项菜单显示之前onPrepareOptionsMenu方法会被调用,你可以用此方法来根据打当时的情况调整菜单", Toast.LENGTH_LONG).show();//如果返回false,此方法就把用户点击menu的动作给消费了,onCreateOptionsMenu方法将不会被调用return true;}}

4、运行程序,检查效果:


童鞋们可以留意一下Activity的三个和选项菜单相关的方法的使用。

5、用xml的方式改写上面的例子,在res中新建一个目录menu,在其中建立一个options_menu.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>

6、更改MainHelloMenu.java的onCreateOptionsMenu()方法,内容如下

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {this.getMenuInflater().inflate(R.menu.options_menu, menu);return true;}

7、再次运行程序查看结果:

两种方法比较,个人感觉还是事先定义好菜单的xml比较好,程序代码部分会比较清晰。

更多相关文章

  1. Android 更新UI的两种方法——handler和runOnUiThread()
  2. Android关于线程更新UI的方法
  3. Android笔记 - 常见错误解决方法 | Android common erros and so
  4. Android 线程优先级设置方法
  5. android开发之设置Edittext密码的方法
  6. Android TextView文字链接4中方法

随机推荐

  1. Android(安卓)APK安装过程及原理详解
  2. android Progressbar使用
  3. Android中设置关键字高亮的方法
  4. Android回调——Android模块化编程
  5. Android加载中动画
  6. android计时demo源代码
  7. 【Android】SQLite使用
  8. 新建Cocos2dx-Android工程
  9. Android(安卓)MediaPlayer基本使用方式
  10. android 动态添加View