【声明】

欢迎转载,但请保留文章原始出处→_→

生命壹号:http://www.cnblogs.com/smyhvae/

文章来源:http://www.cnblogs.com/smyhvae/p/4133292.html

【正文】

从官方文档了解到,从Android3.0(API level 11)开始,Android设备不再要求提供一个专门的菜单按钮,转而推荐使用ActionBar。所以现在市面上很多新设备使用三个虚拟按键,并不再额外提供菜单按钮。

因为Android版本的发展,对于菜单的支持各个版本有很大的区别,而Android3.0是个分水岭,大概可以分为下面三类:

  • OptionMenu和ActionBar:一些操作的集合,如果开发的平台在Android3.0之上,推荐使用ActionBar,如果开发的平台在Android2.3或之下,还是可以使用OptionMenu的。
  • ContextMenu和ActionMode:ContextMenu是一个浮动的窗口形式展现一个选项列表,ActionMode是一个显示在屏幕顶部的操作栏,允许用户选择多个选项,ActionMode在Android3.0之后才有支持。
  • Popup Menu:PopupMenu是固定在View上的模态菜单,以弹出的方式显示,在Android3.0之后才有支持。

【在XML中定义一个菜单】

Android提供了标准的XML格式的资源文件来定义菜单项,并且对所有菜单类型都支持,推荐使用XML资源文件来定义菜单,之后再把它Inflater到Activity或者Fragment中,而不是在Activity中使用代码声明。

而菜单的XML资源文件,需要创建在/res/menu/目录下,并且包含一下几个元素:

  • <menu>:定义一个Menu,是一个菜单资源文件的根节点,里面可以包含一个或者多个<item>和<group>元素。
  • <item>:创建一个MenuItem,代表了菜单中一个选项。
  • <group>:对菜单项进行分组,可以以组的形式操作菜单项。

<item>元素除了常规的id、icon、title属性的支持,还有一个重要的属性:android:showAsAction,这个属性是起兼容性的,描述了在Android的高版本中,菜单项何时以何种方式加入到ActionBar中。

<group>是对菜单进行分组,分组后的菜单显示效果并没有区别,唯一的区别在于可以针对菜单组进行操作,这样对于分类的菜单项,操作起来更方便,提供如下的操作:

  • Menu.setGroupCheckable():菜单组内的菜单是否都可选。
  • Menu.setGroupVisible():是否隐藏菜单组的所有菜单。
  • Menu.setGroupEnabled():菜单组的菜单是否有用。

如果菜单项需要单选或者多选,可以使用android:checkableBehavior属性设置,它可以对单个<item>或者<group>设置一个组,这个属性接受三个参数:single,单选;all,多选,none,没有Checked的选项,默认。

当创建好一个XML菜单资源文件之后,可以使用MenuInflater.inflate()方法填充菜单资源,使XML资源变成一个可编程的对象。

一、Options menu选项菜单:

OptionMenu,选项菜单,单击手机上的菜单键(MENU)出现,必须设备具有菜单按钮才可以触发。因为屏幕的限制,最多只能展示六个菜单项,如果定义的菜单项超出了六个,其他的菜单项将被隐藏,第六个菜单将会显示“更多”,点击展开更多的菜单。虽说在Android3.0之后不再推荐使用选项菜单,但是如果使用了,在Android3.0之后的设备上,选项菜单项将被默认转移到ActionBar中,这个可以通过android:showAsAction属性控制。

创建选项菜单的核心步骤:

(1)重写Activity的onCreateOptionMenu(Menu menu)方法,当菜单第一次被加载时调用

(2)调用Menu 的add( )方法添加菜单项(MenuItem),同时可以调用MenuItem的setIcon()方法为菜单项设置图标(注:Android 3.0之后,即使添加了图标也不会显示)

(3)重写Activity的OptionsItemSelected(MenuItem item)来响应菜单项(MenuItem)的点击事件

来看一下具体的代码实现:

新建Android工程MenuTest:

【方式一】通过配置文件添加Menu选项

(1)在res/menu/main.xml中定义菜单项。main.xml的代码如下:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.menutest.MainActivity" > <item
android:id="@+id/start"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/start"/>
<item
android:id="@+id/over"
android:orderInCategory="200"
android:showAsAction="never"
android:title="@string/over"/>
</menu>

注:第9行和第15行的字符串引用,需要提前在strings.xml文件中设置好。

(2)MainActivity.java:

 package com.example.menutest;

 import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} //重写onCreateOptionMenu(Menu menu)方法,当菜单第一次被加载时调用
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//填充选项菜单(读取XML文件、解析、加载到Menu组件上)
getMenuInflater().inflate(R.menu.main, menu);
return true;
} //重写OptionsItemSelected(MenuItem item)来响应菜单项(MenuItem)的点击事件(根据id来区分是哪个item)
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.start:
Toast.makeText(this, "开始游戏", Toast.LENGTH_SHORT).show();
break;
case R.id.over:
Toast.makeText(this, "结束游戏", Toast.LENGTH_SHORT).show();
break; default:
break;
}
return super.onOptionsItemSelected(item);
}
}

核心代码是第24行:引用布局文件menu.xml,然后在30行的方法中添加MenuItem的点击事件。

运行程序,效果如下:

如果想让MenuItem变成ActionBar的形式,可以修改res/menu/main.xml中的android:showAsAction属性,它的属性值一共有下面几种:

其中,ifRoom表示:如果有空间,就显示出来。withText表示:只显示文本(如果配了图标的话)。如果将属性设置为always,效果如下:

如果需要添加子菜单,可以修改menu.xml文件为如下所示:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.menutest.MainActivity" > <item
android:id="@+id/start"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/start"/>
<item
android:id="@+id/over"
android:orderInCategory="200"
android:showAsAction="never"
android:title="@string/over"/> <!-- 子菜单 -->
<item
android:id="@+id/setting"
android:title="setting">
<menu>
<item
android:id="@+id/setting1"
android:orderInCategory="300"
android:showAsAction="never"
android:title="声音設置"/>
<item
android:id="@+id/setting2"
android:orderInCategory="400"
android:showAsAction="never"
android:title="背景設置"/>
</menu>
</item> </menu>

于是,子菜单的点击事件为:

    public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.start:
Toast.makeText(this, "开始游戏", Toast.LENGTH_SHORT).show();
break;
case R.id.over:
Toast.makeText(this, "结束游戏", Toast.LENGTH_SHORT).show();
break; case R.id.setting1:
Toast.makeText(this, "声音設置", Toast.LENGTH_SHORT).show();
break; case R.id.setting2:
Toast.makeText(this, "背景設置", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}

运行效果如下:

【方式二】通过Java代码添加Menu选项:

当然了,上方的方式一是通过xml文件来添加Menu选项的,下面我们通过Java代码来添加Menu选项(此时已经不需要menu.xml文件了)。修改MainActivity.java,代码如下:

MainActivity.java:

 package com.example.menutest;

 import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.Toast; public class MainActivity extends Activity { private static final int START_ITEM = Menu.FIRST; //Menu.FIRST的值就是1
private static final int OVER_ITEM = Menu.FIRST+1;
private static final int SET_ITEM1 = Menu.FIRST+2;
private static final int SET_ITEM2 = Menu.FIRST+3; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} //重写onCreateOptionMenu(Menu menu)方法,当菜单第一次被加载时调用
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//填充选项菜单(读取XML文件、解析、加载到Menu组件上)
// getMenuInflater().inflate(R.menu.main, menu); //通过代码的方式来添加Menu
//添加菜单项(组ID,菜单项ID,排序,标题)
menu.add(0, START_ITEM, 100, "Start");
menu.add(0, OVER_ITEM, 200, "Over");
//添加子菜单
SubMenu sub1 = menu.addSubMenu("setting");
sub1.add(1, SET_ITEM1, 300, "声音设置");
sub1.add(1, SET_ITEM2, 400, "背景设置"); return true;
} //重写OptionsItemSelected(MenuItem item)来响应菜单项(MenuItem)的点击事件(根据id来区分是哪个item)
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case START_ITEM:
Toast.makeText(this, "开始游戏", Toast.LENGTH_SHORT).show();
break;
case OVER_ITEM:
Toast.makeText(this, "结束游戏", Toast.LENGTH_SHORT).show();
break; case SET_ITEM1:
Toast.makeText(this, "声音設置", Toast.LENGTH_SHORT).show();
break; case SET_ITEM2:
Toast.makeText(this, "背景設置", Toast.LENGTH_SHORT).show();
break; default:
break;
}
return super.onOptionsItemSelected(item);
}
}

注意第35行对各个参数的解释。

运行程序,效果和上方gif图的效果是一样的。

总结:推荐用方式1来做。

二、Context menu:上下文菜单

顾名思义 与上下文(环境)有关。操作时需要长时间按住某个item不放,就会弹出Context menu。效果如下:

创建上下文菜单的核心步骤:

(1)覆盖Activity的onCreateContextMenu(Menu menu)方法,调用Menu的add()方法添加菜单项(MenuItem)

(2)覆盖Activity的onContextItemSelected(MenuItem iitem)来响应事件

(3)调用registerForContextMenu()方法来为视图注册上下文菜单。

现在通过代码来实现。

重新建一个Android工程MenuTest02,步骤如下:

我们现在activity_main.xml中添加一个按钮button1,代码就不写了。然后继续:

(1)在res/menu/main.xml中定义菜单项。main.xml的代码如下:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.menutest02.MainActivity" > <item
android:id="@+id/start"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/start"/>
<item
android:id="@+id/over"
android:orderInCategory="200"
android:showAsAction="never"
android:title="@string/over"/> </menu>

(2)MainActivity.java:

 package com.example.menutest02;

 import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.Button;
import android.widget.Toast; public class MainActivity extends Activity { private Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button)findViewById(R.id.button1);
//为按钮绑定上下文菜单(注意不是绑定监听器)
registerForContextMenu(button1);
} //创建上下文菜单
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo); getMenuInflater().inflate(R.menu.main, menu);
} //上下文菜单的触发事件
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.start:
Toast.makeText(this, "开始···", Toast.LENGTH_SHORT).show();
break; case R.id.over:
Toast.makeText(this, "结束···", Toast.LENGTH_SHORT).show();
break; default:
break;
} return super.onContextItemSelected(item);
} }

核心代码是第22行:为按钮button1绑定上下文菜单。注意不是绑定监听器哦,不要一看到按钮就绑定监听器哈。

注:一个界面中只能有一个上下文菜单。

运行程序,长按button,效果如下:

注:如果是在java代码中添加Menu,用参数menu来天添加就行了。

三、Popup menu:弹出式菜单

 PopupMenu,弹出菜单,一个模态形式展示的弹出风格的菜单,绑在在某个View上,一般出现在被绑定的View的下方(如果下方有空间)。

注意:弹出菜单是在API 11和更高版本上才有效的。

核心步骤:

(1)通过PopupMenu的构造函数实例化一个PopupMenu对象,需要传递一个当前上下文对象以及绑定的View。

(2)调用PopupMenu.setOnMenuItemClickListener()设置一个PopupMenu选项的选中事件。

(3)使用MenuInflater.inflate()方法加载一个XML文件到PopupMenu.getMenu()中。

(4)在需要的时候调用PopupMenu.show()方法显示。

现在通过代码来实现。重新新建一个工程文件MenuTest03。步骤如下:

先在布局文件activity_main.xml中加一个按钮,代码略。

(1)在res/menu/main.xml中定义菜单项。main.xml的代码如下:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.menutest03.MainActivity" > <item
android:id="@+id/copy"
android:orderInCategory="100"
android:title="复制"/> <item
android:id="@+id/delete"
android:orderInCategory="100"
android:title="粘贴"/> </menu>

(2)MainActivity.java:

 package com.example.menutest03;

 import android.app.Activity;import android.os.Bundle;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener,OnMenuItemClickListener{ private Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(this);
} //点击按钮后,加载弹出式菜单
@Override
public void onClick(View v) {
//创建弹出式菜单对象(最低版本11)
PopupMenu popup = new PopupMenu(this, v);//第二个参数是绑定的那个view
//获取菜单填充器
MenuInflater inflater = popup.getMenuInflater();
//填充菜单
inflater.inflate(R.menu.main, popup.getMenu());
//绑定菜单项的点击事件
popup.setOnMenuItemClickListener(this);
popup.show(); //这一行代码不要忘记了 } //弹出式菜单的单击事件处理
@Override
public boolean onMenuItemClick(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.copy:
Toast.makeText(this, "复制···", Toast.LENGTH_SHORT).show();
break; case R.id.delete:
Toast.makeText(this, "删除···", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return false;
} }

注意14行代码绑定了两个监听器:OnClickListener和OnMenuItemClickListener。 在绑定OnMenuItemClickListener监听器时,选的是下面这个:

如果是在API 14及以上版本,32行34行可以合并为:popup.inflate(R.menu.main, popup.getMenu());

注意第37行代码不要忘记show。

运行程序,单击button,效果如下:

最后,附上整个文章的代码:

【工程文件】

链接:http://pan.baidu.com/s/1eQ6EnUq

密码:438o

Android系列之UI组件----Menu菜单的更多相关文章

  1. ReactNative Android之原生UI组件动态addView不显示问题解决

    ReactNative Android之原生UI组件动态addView不显示问题解决 版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:http://www.cnblogs.com ...

  2. Android动态修改ToolBar的Menu菜单

    Android动态修改ToolBar的Menu菜单 效果图 实现 实现很简单,就是一个具有3个Action的Menu,在我们滑动到不同状态的时候,把对应的Action隐藏了. 开始上货 Menu Me ...

  3. Android开发 ---基本UI组件4:拖动事件、评分进度条、圆圈式进度条、进度条控制

    Android开发 ---基本UI组件4 1.activity_main.xml 描述: 定义了一个按钮 <?xml version="1.0" encoding=" ...

  4. Android开发 ---基本UI组件3:单选按钮、多选按钮、下拉列表、提交按钮、重置按钮、取消按钮

    Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个用户注册按钮 <?xml version="1.0" encoding=&q ...

  5. Android开发 ---基本UI组件2:图像按钮、单选按钮监听、多选按钮监听、开关

    Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个按钮 <?xml version="1.0" encoding=" ...

  6. Android经常使用UI组件 - TextView

    TextView是Android里面用的最多的UI组件,一般使用在须要显示一些信息的时候,其不能输入,仅仅能初始设定或者在程序中改动. 实例:TextViewDemo 执行效果: 代码清单: 布局文件 ...

  7. Android经常使用UI组件 - Button

    button(Button)是Android其中一个经常使用的UI组件.非常小可是在开发中最经常使用到.一般通过与监听器结合使用.从而触发一些特定事件. Button继承了TextView.它的功能就 ...

  8. 【Android】6.0 添加Menu菜单组件、Intent启动活动、显式Intent、隐式Intent

    1.0 在helloworld项目基础上创建活动SecondActivity: 2.0 其中main.xml: <?xml version="1.0" encoding=&q ...

  9. Android学习笔记⑤——UI组件的学习TextView相关

    TextView是一个强大的视图组件,直接继承了View,同时也派生出了很多子类,TextView其作用说白了就是在布局中显示文本,有点像Swing编程中的JLabel标签,但是他比JLabel强大的 ...

随机推荐

  1. Android性能优化之一:ViewStub

    ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View.虽然Android开发人员基本上都听说过,但是真正用的可能不多. ViewStub可以理解成一个非常轻量级的Vie ...

  2. linux backlog深入剖析以及netty设置backlog

    netty不同于socket,其上次API没有提供设置backlog的选项,而是依赖于操作系统的somaxconn和tcp_max_syn_backlog,对于不同OS或版本,该值不同,建议根据实际并 ...

  3. 用javascript实现全选/反选组件

    以下是本人制作的全选/反选 组件,供广大同行参考.指正: 效果如图: 在实现的过程中,全选和全部取消选中这两个功能较为简单,只需用for循环遍历所有复选框为true或false即可.反选也较为简单,也 ...

  4. CSS之浮动那些事

    1.清除浮动 下面是两种常用的方式,而这两招也够用了(不用千招会,只需一招精). 1.结尾处加空div标签 clear:both <style type="text/css" ...

  5. ASP.NET MVC another entity of the same type already has the same primary key value

    ASP.NET MVC项目 Repository层中,Update.Delete总是失败 another entity of the same type already has the same pr ...

  6. 浅谈Base64编码算法

    一.什么是编码解码 编码:利用特定的算法,对原始内容进行处理,生成运算后的内容,形成另一种数据的表现形式,可以根据算法,再还原回来,这种操作称之为编码. 解码:利用编码使用的算法的逆运算,对经过编码的 ...

  7. Android——检查网络是否已经链接

    新建一个项目testNet 添加一个button layout.xml: <RelativeLayout xmlns:android="http://schemas.android.c ...

  8. HDFS主要特性和体系结构

    引言 Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统.它和现有的分布式文件系统有很多共同点.但同时,它和其他的分布式文件系统 ...

  9. NSString、NSArray、NSDictionary和NSData的数据存储

    #import "ViewController.h" @interface ViewController () @end @implementation ViewControlle ...

  10. CSS 子选择器(六)

    一.子选择器 子选择器中前后部分之间用一个大于号隔开,前后两部分选择符在结构上属于父子关系. 子选择器是根据左侧选择符指定的父元素,然后在该父元素下寻找匹配右侧选择符的子元素. 二.简单例子 < ...