一、OptionMenu(选项菜单)
通过查阅api文档可知,add方法的返回值是一个MenuItem对象,每一个MenuItem对象对应一个菜单项。可以通过MenuItem接口的相应方法来设置与菜单项相关的内容,
例如,下面的代码设置了菜单项的图像:
我们还可以使用MenuItem接口的setIntent方法将一个activity与菜单项关联,setIntent方法的定义如下:
android中最常用的就是选项菜单(optionsMenu), 该菜单在点击 menu 按键后会在对应的Activity底部显示出来。并且每个Activity 都可以选择处理这一请求,一般情况下,选项菜单最多显示2排每排3个菜单项,这些菜单项有文字有图标,也被称作Icon Menus,如果多于6项,从第六项开始会被隐藏,第六项会出现一个More,点击More才出现第六项及以后的菜单项.
以上陈述的是在3.0版之前选项菜单的显示形式,3.0版后由于加入了新的属性ActionBar,添加选项菜单后被显示在ActionBar中,手机上物理按键也渐渐的被去掉。选项菜单还可设置显示在屏幕下方。
Activity类的 public boolean onCreateOptionsMenu(Menu menu){ } 方法用来创建选项菜单,一般需要将创建选项菜单的代码放在onCreateOptionsMenu()方法里边,通过Menu接口的add方法可以添加一个选项菜单,该方法有四种重载形式:
- public MenuItem add(CharSequence title);
- public MenuItem add(int titleRes);
- public MenuItem add(int groupId, int itemId, int order, CharSequence title);
- public MenuItem add(int groupId, int itemId, int order, int titleRes);
add方法最多有4个参数,这些参数的含义如下:
groupId:菜单项的分组ID,该参数一般用于带选项按钮的菜单。参数值可以是负整数、0和正整数。
itemId:当前添加的菜单项的ID。该参数值可以是负整数、0和正整数。
order:菜单显示顺序。Android系统在显示菜单项时,根据order参数的值按升序从左到右、从上到下显示菜单项。参数值必须是0和正整数,不能为负整数。
titleRes或title:菜单项标题的字符串资源ID或字符串。
如果使用add方法的前两种重载形式,groupId、itemId和order三个参数的值都为0。这时菜单项的显示顺序就是菜单项的添加顺序。下面的代码添加了3个选项菜单项:
- public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(1, 1, 1, "菜单项1");
- menu.add(1, 2, 2, "菜单项2");
- menu.add(1, 3, 3, "菜单项3");
- return true;
- }
- MenuItem deleteMenuItem = menu.add(1, 1, "删除");
- deleteMenuItem.setIcon(R.drawable.delete);
- public MenuItem setIntent(Intent intent);
将一个Activity与菜单项关联后,单击该菜单项,系统会调用startActivity方法显示与菜单项关联的Activity。
下面的代码将AddActivity与"添加"菜单项关联,单击"添加"菜单项,系统就会显示AddActivity。
- MenuItem addMenuItem = menu.add(1, 1, 1, "添加");
- //将AddActivity与“添加”菜单项进行关联
- addMenuItem.setIntent(new Intent(this, AddActivity.class));
但是,如果设置了菜单项的单击事件,则与菜单项关联的Activity将失效。也就是说,系统将会调用单击事件方法,而不会显示与菜单项关联的Activity了。
二、ContextMenu(上下文菜单)
Android的上下文菜单,当一个视图注册到一个上下文菜单时,执行一个在该视图对象上的“长按”动作,将出现一个提供相关功能的浮动菜单。上下文菜单可被注册到任何视图中。但不支持图标或快捷键。示例代码:
- menu.add(1, 1, 1, "菜单项1").setOnMenuItemClickListener(this);
- public boolean onMenuItemClick(MenuItem item) {
- if (item.getItemId() == 3) {
- Toast.makeText(this, "你选的是dajb", Toast.LENGTH_SHORT).show();
- return true;
- }
- return false;
- }
三、SubMenu(子菜单)
SubMenu(子菜单)是在选项菜单的基础上增加的菜单。
子菜单不支持嵌套,即子菜单中不能再包括其他子菜单。一个Menu对象可以拥有0或多个SubMenu,通过调用Menu.addSubMenu方法将SubMenu添加到当前Menu中。
在SubMenu添加MenuItem的方式和在Menu中添加MenuItem方式一样,因为SubMenu是Menu的子类,但是SubMenu里不能再添加SubMenu。
与add()方法一样它有四个重载方法,参数也同出一辙。
- public abstract SubMenu addSubMenu(int titleRes)
- public abstract SubMenu addSubMenu(CharSequence title)
- public abstract SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes)
- public abstract SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title)
常用的和menu菜单相关的方法有:
public boolean onCreateOptionsMenu(Menu menu):使用此方法调用OptionsMenu。
public void onOptionsMenuClosed(Menu menu):菜单关闭后发生的动作。
public boolean onPrepareOptionsMenu(Menu menu):选项菜单显示之前onPrepareOptionsMenu方法会被调用,你可以用此方法来根据打当时的情况调整菜单。
public boolean onMenuOpened(int featureId, Menu menu):
菜
单打开后发生的动作。
三种菜单的点击事件 —— 处理菜单点击事件的方法有四种:
第一种、直接复写activity的onOptionsItemSelected方法,这种方法只限于OptionMenu(选项菜单) 和 SubMenu(子菜单)
第二种、直接复写activity的onMenuItemSelected方法,这种方法适用于三种菜单
第三种、先实现android.view.MenuItem.OnMenuItemClickListener接口,然后重写onMenuItemClick(MenuItem item)方法,这种方法只适用于OptionMenu(选项菜单)
第四种、直接复写activity的onContextItemSelected方法,这种方法只适用于ContextMenu(上下文菜单)
这四种方法都有一个MenuItem 类型的item参数,可以根据MenuItem接口的相应方法(例如getTitle和getId)判断单击的是哪个项。
如果同时使用了适用于某一种菜单的所有方法的话:
对于OptionMenu来讲:
当onMenuItemClick返回true时,其余事件全部失效
当onMenuItemClick返回false时,除onContextItemSelected之外的三种方法都会被调用
对于SubMenu(子菜单) 来讲:
无论onMenuItemClick方法返回值是什么,都会调用onMenuItemSelected和onOptionsItemSelected两个方法
而对于ContextMenu来讲:
无论onMenuItemClick方法返回值是什么,都会调用onMenuItemSelected和onContextItemSelected两个方法
直接上一个完整示例:
- public class MainActivity extends Activity implements OnMenuItemClickListener{
- Button mButton1;
- Button mButton2;
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mButton1 = (Button)findViewById(R.id.button1);
- mButton2 = (Button)findViewById(R.id.button2);
- // 注册一个视图到上下文菜单
- registerForContextMenu(mButton1);
- registerForContextMenu(mButton2);
- }
- public boolean onCreateOptionsMenu(Menu menu) {
- //通过Menu接口的add方法可以添加一个OptionMenu(选项菜单)
- MenuItem menuitem1 = menu.add(0, 1, 1, "menuitem1");
- MenuItem menuitem2 = menu.add(0, 2, 2, "menuitem2");
- //此处通过MenuItem接口的setOnMenuItemClickListener方法可以设置菜单项的单击事件。
- menuitem1.setOnMenuItemClickListener(this);
- menuitem2.setOnMenuItemClickListener(this);
- //添加子菜单
- SubMenu subMenu = menu.addSubMenu(0, 7, 7, "subMenu");
- subMenu.add(0, 8, 8, "subMenu1");
- subMenu.add(0, 9, 9, "subMenu2");
- //使用布局文件的方式增加菜单
- getMenuInflater().inflate(R.menu.mymenu, menu);
- return super.onCreateOptionsMenu(menu);
- }
- //创建ContextMenu(上下文菜单)
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
- if(v==mButton1){
- menu.setHeaderTitle("Context Menu 1");
- menu.add(0, 3, 3, "Context Menu 1_1");
- menu.add(0, 4, 4, "Context Menu 1_2");
- }
- else if(v==mButton2){
- menu.setHeaderTitle("Context Menu 2");
- menu.add(0, 5, 5, "Context Menu 2_1");
- menu.add(0, 6, 6, "Context Menu 2_2");
- }
- super.onCreateContextMenu(menu, v, menuInfo);
- }
- //直接复写activity的onOptionsItemSelected方法,
- //这种方法只限于OptionMenu(选项菜单) 和 SubMenu(子菜单)
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()){
- case 1:
- System.out.println("onOptionsItemSelected....OptionMenu....menuitem1");
- break;
- case 2:
- System.out.println("onOptionsItemSelected....OptionMenu....menuitem2");
- break;
- case 3:
- System.out.println("onOptionsItemSelected....ContextMenu....Context Menu 1_1");
- break;
- case 5:
- System.out.println("onOptionsItemSelected....ContextMenu....Context Menu 2_1");
- break;
- case 8:
- System.out.println("onOptionsItemSelected....SubMenu....subMenu1");
- break;
- case 9:
- System.out.println("onOptionsItemSelected....SubMenu....subMenu2");
- break;
- }
- return false;
- }
- //直接复写activity的onMenuItemSelected方法,这种方法适用于三种菜单
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- switch (item.getItemId()){
- case 1:
- System.out.println("onMenuItemSelected....OptionMenu....menuitem1");
- break;
- case 2:
- System.out.println("onMenuItemSelected....OptionMenu....menuitem2");
- break;
- case 3:
- System.out.println("onMenuItemSelected....ContextMenu....Context Menu 1_1");
- break;
- case 5:
- System.out.println("onMenuItemSelected....ContextMenu....Context Menu 2_1");
- break;
- case 8:
- System.out.println("onMenuItemSelected....SubMenu....subMenu1");
- break;
- case 9:
- System.out.println("onMenuItemSelected....SubMenu....subMenu2");
- break;
- }
- return super.onMenuItemSelected(featureId, item);
- }
- /*
- 菜单项的单击事件类先去实现OnMenuItemClickListener接口,
- 即android.view.MenuItem.OnMenuItemClickListener,
- 然后去重写onMenuItemClick(MenuItem item)方法。这种方法只适用于OptionMenu(选项菜单)
- */
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()){
- case 1:
- System.out.println("onMenuItemClick....OptionMenu....menuitem1");
- break;
- case 2:
- System.out.println("onMenuItemClick....OptionMenu....menuitem2");
- break;
- case 3:
- System.out.println("onMenuItemClick....ContextMenu....Context Menu 1_1");
- break;
- case 5:
- System.out.println("onMenuItemClick....ContextMenu....Context Menu 2_1");
- break;
- case 8:
- System.out.println("onMenuItemClick....SubMenu....subMenu1");
- break;
- case 9:
- System.out.println("onMenuItemClick....SubMenu....subMenu2");
- break;
- }
- return false;
- }
- //这种方法只适用于ContextMenu(上下文菜单)
- public boolean onContextItemSelected(MenuItem item) {
- switch (item.getItemId()){
- case 1:
- System.out.println("onContextItemSelected....OptionMenu....menuitem1");
- break;
- case 2:
- System.out.println("onContextItemSelected....OptionMenu....menuitem2");
- break;
- case 3:
- System.out.println("onContextItemSelected....ContextMenu....Context Menu 1_1");
- break;
- case 5:
- System.out.println("onContextItemSelected....ContextMenu....Context Menu 2_1");
- break;
- case 8:
- System.out.println("onContextItemSelected....SubMenu....subMenu1");
- break;
- case 9:
- System.out.println("onContextItemSelected....SubMenu....subMenu2");
- break;
- }
- return true;
- }
- }
自定义menu:
在 Android 中任何视图组件的创建方式都有两种:
1、在XML文件中创建;
2、在代码中创建。
Menu 也不例外,我们既可以在资源文件中声明,也可以在代码中创建。
Android中的3种菜单都可以在XML文件中声明定义,在代码中通过MenuInflater 类来使用。
Menu 资源文件存放于工程的res\menu目录下。通过R.menu.name 的方式来引用。
Menu 资源文件的结构:
1、<menu>根元素,在<menu>根元素里面会嵌套<item>和<group>子元素,<menu>根元素没有属性。
2、<item>元素中也可嵌套<menu>形成子菜单。
3、<group>表示一个菜单组,相同的菜单组可以一起设置其属性,例如visible、enabled和checkable等。
<group>元素的属性说明 如下:
— id:唯一 标示该菜单组的引用id。
— menuCategory:对菜单进行分类,定义菜单的优先级,有效值为container、system、secondary和alternative。
— orderInCategory:一个分类 排序整数。
— checkableBehavior:选择 行为,单选、多选还是其他。有效值为none、all和single。
— visible:是否可见,true或者false。
— enabled:是否可用,true或者false。
<item>表示菜单项,包含在<menu>或<group>中的有效属性。
<item>元素的属性说明如下:
— id:唯一标示菜单的ID引用。
— menuCategory:菜单分类。
— orderInCategory:分类排 序。
— title:菜单标题字符串。
— titleCondensed:浓缩标题, 适合标题太长的时候使用。
— icon: 菜单的图标。
— alphabeticShortcut:字 符快捷键。
— numericShortcut:数字快捷键。
— checkable:是否可选。
— checked:是否已经被选。
— visible:是否可见。
— enabled:是否可用。