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

选项菜单:最常规的菜单,android中把它叫做option menu

子菜单:android中点击子菜单将弹出悬浮窗口显示子菜单项。子菜单不支持嵌套,即子菜单中不能再包括其他子菜单。

上下文菜单:android中长按视图控件后出现的菜单,windows点击右键弹出的菜单即上下文菜单

图标菜单:这个比较简单,就是带icon的菜单项,需要注意的是子菜单项、上下文菜单项、扩展菜单项均无法显示图标

 

创建options menu

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

Java代码  
  1. @Override  
  2. public boolean onCreateOptionsMenu(Menu menu) {  
  3.     // 虽然目前android还没有系统菜单,但是为了兼容到以后的版本,最好加上  
  4.     super.onCreateOptionsMenu(menu);  
  5.     // 第一个参数代表组号,android中你可以给菜单分组,以便快速地操作同一组的菜单。  
  6.     // 第二个参数代表Menu的唯一的ID号,可以自己指定,也可以让系统来自动分配,在响应菜单时你需要通过ID号来判断点击了哪个菜单。  
  7.     // 第三个参数代表Menu显示顺序的编号,编号小的显示在前面。  
  8.     // 第四个参数代表标题  
  9.     menu.add(0, MENUITEM1, MENUITEM1, "关于");  
  10.     menu.add(0, MENUITEM2, MENUITEM2, "帮助");  
  11.     menu.add(0, MENUITEM3, MENUITEM3, "更多");  
  12.   
  13.     return true;  
  14. }  

 可以对Menu进行分组:

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, 11"item 1");  
  8.     menu.add(group1, 22"item 2");  
  9.     menu.add(gourp2, 33"item 3");  
  10.     menu.add(gourp2, 44"item 4");  
  11.     return true;  
  12. }  

 分组之后就能使用menu中提供的方法对组进行操作了,如下:menu.removeGroup(group1); //删除一组菜单

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(Menu Item)回调方法,每当有菜单项被点击时,android就会调用该方法,并传入被点击菜单项。

 @Override

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

 2.使用监听器

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

第一步:创建监听器类

Java代码  
  1. class MenuItemListener implements OnMenuItemClickListener {  
  2.     // 该方法先于onOptionsItemSelected执行。  
  3.     @Override  
  4.     public boolean onMenuItemClick(MenuItem item) {  
  5.         return false;  
  6.     }  
  7. }  

 

 第二步:为菜单项注册监听器

Java代码  
  1. menu.getItem(0).setOnMenuItemClickListener(new MenuItemListener()); // 为MenuItem添加监听事件  

 3.使用Intent响应菜单

Java代码  
  1. menu.getItem(1).setIntent(new Intent()); // 可以为MenuItem添加Intent  

 

子菜单sub Menu

Android支持子菜单,你可以通过addSubMenu(int groupId, int itemId, int order, int titleRes)方法创建和响应子菜单。

Java代码  
  1. /** 
  2.  * 使用的最多方法是重写activity类的 onOptionsItemSelected(Menu 
  3.  * Item)回调方法,每当有菜单项被点击时,android就会调用该方法,并传入被点击菜单项。 
  4.  */  
  5. @Override  
  6. public boolean onPrepareOptionsMenu(Menu menu) {  
  7.     Resources res = getBaseContext().getResources();  
  8.     // 第一个参数代表组号,android中你可以给菜单分组,以便快速地操作同一组的菜单。  
  9.     // 第二个参数代表Menu的唯一的ID号,可以自己指定,也可以让系统来自动分配,在响应菜单时你需要通过ID号来判断点击了哪个菜单。  
  10.     // 第三个参数代表Menu显示顺序的编号,编号小的显示在前面。  
  11.     // 第四个参数代表标题  
  12.     SubMenu about = menu.addSubMenu(0, MENUITEM1, MENUITEM1, "关于"); // 添加菜单项(多种方式)  
  13.     SubMenu help = menu.addSubMenu(0, MENUITEM2, MENUITEM2, "帮助");  
  14.     SubMenu more = menu.addSubMenu(0, MENUITEM3, MENUITEM3, "更多");  
  15.     // 为MenuItem设置图标  
  16.     about.setIcon(res.getDrawable(R.drawable.ic_launcher));  
  17.     help.setIcon(res.getDrawable(R.drawable.ic_launcher));  
  18.     more.setIcon(res.getDrawable(R.drawable.ic_launcher));  
  19.   
  20.     // 为more菜单添加子订单  
  21.     MenuItem display = more.add(0, MENUITEM3, MENUITEM3, "设置");  
  22.     display.setIcon(R.drawable.ic_launcher);// 子菜单项不支持显示图标,这样做是没意义的,尽管不会报错!  
  23.     more.add(0, MENUITEM3, MENUITEM3, "退出");  
  24.     more.setHeaderIcon(R.drawable.ic_launcher); // 以添加子菜单项栏目的标题图标  
  25.   
  26.     return true;  
  27. }  

 Menu可以包含多个SubMenu,SubMenu可以包含多个MenuItem,但是SubMenu不能包含SubMenu,及子菜单不能嵌套

 

图标菜单icon Menu

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

· 扩展的菜单项

· 子菜单的菜单项

· 上下文菜单的菜单项

除此以外,带Icon的菜单项不能加上复选框(check mark)。

 

 

上下文菜单ContextMenu

android是通过长按某个视图元素来弹出上下文菜单的,图标和子菜单都无法用在Android的上下文菜单项中。

上下文菜单继承了android.view.Menu,因此我们可以像操作Options Menu那样给上下文菜单增加菜单项。上下文菜单与Options Menu最大的不同在于,Options Menu的拥有者是Activity,而上下文菜单的拥有者是Activity中的View。每个Activity有且只有一个Options Menu,它为整个Activity服务。而一个Activity往往有多个View,并不是每个View都有上下文菜单,这就需要我们显示地通过registerForContextMenu(Viewview)来指定

尽管上下文菜单的拥有者是View,生成上下文菜单却是通过Activity中的onCreateContextMenu(ContextMenu menu, View v,ContextMenu.ContextMenuInfo menuInfo)方法,该方法很像生成Options Menu的onCreateOptionsMenu(Menu menu)方法。两者的不同在于,onCreateOptionsMenu只在用户第一次按“Menu”键时被调用,而onCreateContextMenu会在用户每一次长按View时被调用,而且View必须已经注册了上下文菜单。

另一个值得注意的就是ContextMenuInfo,该类的对象被传入onCreateContextMenu(ContextMenu menu, View v,ContextMenu.ContextMenuInfo menuInfo)方法,那么它有什么用呢?有时候,视图元素需要向上下文菜单传递一些信息,比如该View对应DB记录的ID等,这就要使用ContextMenuInfo。需要传递额外信息的View需要重写getContextMenuInfo()方法,返回一个带有数据的ContextMenuInfo实现类对象。

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

Java代码  
  1. public class MyListActivity extends ListActivity {  
  2.   
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.two);  
  7.         simpleShowList();  
  8.   
  9.         this.registerForContextMenu(getListView());  
  10.     }  
  11.   
  12.     private void simpleShowList() {  
  13.         String[] item = new String[] { "ListItem1""ListItem2""ListItem3", ListItem4" };  
  14.         ArrayAdapter adapter = new ArrayAdapter(this,  
  15.                 android.R.layout.simple_list_item_1, item);  
  16.         this.setListAdapter(adapter);  
  17.     }  
  18. }  
 

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

Java代码  
  1. @Override  
  2. public void onCreateContextMenu(ContextMenu menu, View v,  
  3.         ContextMenuInfo menuInfo) {  
  4.     menu.setHeaderTitle("文件操作");  
  5.     menu.add(01, Menu.NONE, "发送");  
  6.     menu.add(02, Menu.NONE, "复制");  
  7.     menu.add(03, Menu.NONE, "重命名");  
  8.     menu.add(04, Menu.NONE, "删除");  
  9. }  
  

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

 

Java代码  
  1. @Override  
  2. public boolean onContextItemSelected(MenuItem item) {  
  3.     // 得到当前被选中的item信息  
  4.     AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();  
  5.     switch (item.getItemId()) {  
  6.     case 1:   
  7.         break;  
  8.     case 2:   
  9.         break;  
  10.     case 3:   
  11.         break;  
  12.     case 4:  
  13.         break;  
  14.     default:  
  15.         return super.onContextItemSelected(item);  
  16.     }  
  17.     return true;  
  18. }  
 

 

Menu关闭

如果需要动态的显示菜单可以在菜单关闭时进行相应的清除处理:

Java代码  
  1. @Override  
  2. public void onOptionsMenuClosed(Menu menu) {  
  3.     menu.clear();  
  4.     super.onOptionsMenuClosed(menu);  
  5. }  

更多相关文章

  1. Android中使用Handler机制更新UI的两种方法
  2. Android中设置关键字高亮的方法
  3. 在android获取root权限的方法^_^。
  4. Android CheckBox控件使用OnClickListener和OnCheckedChangeList
  5. Android Studio安装app 报错的问题It is possible that this iss
  6. Google Maps API Key申请方法及地址

随机推荐

  1. Android -- 文字设置超链接
  2. android计算器
  3. android 获取sd卡根目录
  4. Android 获得当前进程PackageName
  5. android 4.0 屏蔽home键实现
  6. Android VelocityTracker使用总结
  7. android 轮播图无限循环,自动播放
  8. android Handler内存泄露 kotlin内存泄露
  9. Android(安卓)setbackgroundcolor()方法
  10. Android点击EditText以外区域隐藏键盘Fra