概念
在Android的应用程序中,菜单可分为两种:一种是选项菜单(Option Menu),另一种是上下文菜单(Context Menu)。选项菜单是指,当用户按下菜单键后出现的菜单;上下文菜单是当用户在某个View对象上长按时出现的菜单,类似于Windows平台下的鼠标右键。
Android系统中,每个Activity有且仅有一个Option Menu对象;而Context Menu是针对View的,一个View有且仅有一个Context Menu对象。
(1)选项菜单 特点:
菜单项属性
名称 | 描述 |
groupId | 群组号,指定该菜单所属的群组,便于同时对多个菜单项进行操作 |
itemId | 单个菜单项的号,可以针对单独的菜单项操作 |
order | 指定该菜单在菜单框中出现的次序 |
title | 该菜单项的标题 |
(2)上下文菜单 特点:
Activity中的每个VIew都可以指定不同的上下文菜单,但实际开发中,上下文菜单多用于列表类,比如联系人列表、短信列表等,由于列表类视图中所有的列表项都在一个ListView里面,所以单击里面的每一个列表项,弹出的上下文菜单都是一样的。
创建Option Menu
Option Menu 内部调用的流程
注意:当Activity启动的时候,系统会调用onCreateOptionMenu方法,仅且调用一次,主要完成菜单的初始化工作,可以在此处给选项菜单中添加新的菜单项,在随后的Activity活动中,不会再调用此方法。
用户每次按下菜单键,系统会调用onPrepareOptionsMenu方法,可以在该方法里面添加一些动态改变菜单内容的代码,比如可以根据当前的需求,隐藏一些不需要的菜单项,或者再添加一些菜单项。onPrepareOptionsMenu的默认操作就是弹出已有的选项菜单。
用户选择某个菜单项时,系统会调用onOptionsItemSelected方法,可以重写该方法来实现具体的应用需求。
用户取消菜单或者执行完onOptionsItemSelected方法后,系统都会调用onOptionsMenuClosed方法,该方法默认操作是隐藏菜单框,一般不重写。
实例代码:特别注意返回值的意义
1 @Override 2 public boolean onCreateOptionsMenu(Menu menu) { 3 //MenuItem menu.add(int groupId,int itemId,int order,CharSequence title); 4 menu.add(0,1,Menu.NONE,"Setting"); 5 menu.add(0,2,Menu.NONE,"Exit"); 6 return true; 7 //返回值一般为true,意味着系统可以继续处理剩下的逻辑,比如将菜单框显示在用户界面上 8 //如果返回为false,那么系统将不再做任何的处理 9 } 10 @Override 11 public boolean onOptionsItemSelected(MenuItem item) { 12 // TODO Auto-generated method stub 13 int id = item.getItemId(); 14 switch(id){ 15 case 1://设置 16 Toast.makeText(this, "Setting", Toast.LENGTH_SHORT).show(); 17 break; 18 case 2://退出 19 Toast.makeText(this, "Exit", Toast.LENGTH_SHORT).show(); 20 break; 21 default:; 22 } 23 return false; 24 //返回值为false代表继续执行系统内部的默认处理,比如选择菜单后,菜单框一般会隐藏 25 //返回值为true,代表中止继续执行,菜单框不会隐藏 26 //return super.onOptionsItemSelected(item); 27 }
创建 Context Menu
在Activity启动时,系统并没有创建上下文菜单的函数调用,而是程序猿更加需要,在onCreate方法里面注册需要上下文菜单的视图。注册的方法调用registerForContextMenu(View),传入的参数是需要上下文菜单的视图对象。
Context Menu 启动流程
Context Menu 的生命周期仅在onCreateContextMenu和onContextMenuClosed之间,更新Context Menu 里面的菜单项只能在onCreateContextMenu里面进行;Option Menu在Activity启动后的整个生命周期都有效,可以通过Option Menu的引用去随时更新Option Menu的菜单项。
样例代码:
1 @Override 2 public boolean onContextItemSelected(MenuItem item) { 3 //一个Activity中,所有的Context Menu调用同一个onContextItemSelected方法 4 int itemid = item.getItemId(); 5 if(item.getGroupId() == 2){ 6 TextView tv = (TextView)findViewById(R.id.state); 7 switch(itemid){ 8 case 21: 9 tv.setText("Hidden"); 10 mIsGroupVisible = false; 11 Toast.makeText(this, "Hidden item GroupId equal to 1", Toast.LENGTH_SHORT).show(); 12 flush(mChecked); 13 mChecked[0]=true; 14 break; 15 case 22: 16 tv.setText("Display"); 17 mIsGroupVisible = true; 18 Toast.makeText(this, "Display item GroupId equal to 1", Toast.LENGTH_SHORT).show(); 19 flush(mChecked); 20 mChecked[1]=true; 21 break; 22 default:; 23 } 24 }else{ 25 TextView tv = (TextView)findViewById(R.id.result); 26 String title = item.getTitle().toString(); 27 tv.setText("Choose id:"+itemid+" ,title:"+title); 28 } 29 30 return super.onContextItemSelected(item); 31 } 32 private void flush(boolean[] mChecked2) { 33 // TODO Auto-generated method stub 34 mChecked2[0]= false; 35 mChecked2[1]= false; 36 } 37 private boolean mIsGroupVisible = false; 38 private boolean mChecked[]={true,false,false}; 39 40 @Override 41 public void onCreateContextMenu(ContextMenu menu, View v, 42 ContextMenuInfo menuInfo) { 43 44 Resources res = getResources(); 45 Drawable icon = res.getDrawable(R.drawable.ic_launcher); 46 switch(v.getId()){ 47 //Android 并没有为每一个View提供单独的onCreateContextMenu方法 48 //so,要根View的id值来区分 49 case R.id.background: 50 if(menu.hasVisibleItems())return; 51 menu.add(0,1,Menu.NONE,"金").setIcon(icon);//Context Menu 不能显示图标 52 menu.add(1,2,Menu.NONE,"甲"); 53 menu.add(0,3,Menu.NONE,"木"); 54 menu.add(1,4,Menu.NONE,"乙"); 55 menu.add(0,5,Menu.NONE,"水"); 56 menu.add(1,6,Menu.NONE,"丙"); 57 menu.add(0,7,Menu.NONE,"火"); 58 menu.add(1,8,Menu.NONE,"丁").setIcon(icon); 59 menu.add(0,9,Menu.NONE,"土"); 60 menu.setGroupVisible(1, mIsGroupVisible); 61 break; 62 case R.id.state: 63 //设置单选或复选菜单 Option Menu和Context Menu都可用,常用于Context Menu 64 //单选菜单,在菜单群组中各菜单项互斥 65 //调用setGroupCheckable方法 void setGroupCheckable(int groupId,boolean checkable, boolean exclusive); 66 //groupId指定设置的群组 67 //checkable指定群组是否可选,true可选 68 //exclusive 指定该项是否为互斥,true单选,false多选 69 menu.add(2,21,Menu.NONE,"Hidden_Group1").setChecked(mChecked[0]); 70 menu.add(2,22,Menu.NONE,"Display_Group1").setChecked(mChecked[1]); 71 menu.setGroupCheckable(2, true, true); 72 73 break; 74 default:; 75 } 76 super.onCreateContextMenu(menu, v, menuInfo); 77 }
子菜单、单选与复选菜单 参考上例代码。
在XML文件中描述菜单
XML语法中,有3个元素用来描述菜单,分别是<menu> <item> 和<group>