Android中的菜单
本文参考自官方文档:https://developer.android.com/guide/topics/ui/menus.html
Android为了维护app之间一个统一的操作习惯,提供了Menus来处理用户和Activity之间的一些交互。但是在不同的系统版本上面推荐的Menu不一样。比如在android 3.0以下,由于Google会要求所有设备生产商提供一个菜单的实体键,所以在3.0一下菜单的主要弹出方式就是点击菜单实体键,弹出6个条目的菜单面板。在3.0以后,引入ActionBar,打开菜单行为转变成点击ActionBar上面的overflow按钮。这两种菜单面板的操作一般都是影响到整个app的操作。
下图是3.0一下的Option Menu的样子:

这是3.0上的ActionBar的样子:

当然除了上面提到的菜单面板,Android还提供了上下文菜单(Context menu)和弹出菜单(Popup Menu)。尽管存在三种不同的菜单,但是Android提供了一个统一操作的API。
在XML中定义菜单项
Android中的所有菜单项的布局文件都是在res/menu目录下定义的,布局文件并没有和某一种菜单类型绑定,这就是为什么前面说有统一操作的API。xml定义菜单的规则是:顶层元素必须是Menu;在Menu中可以放置item和group;item表示菜单中的一项;group可以包含多个item,其中的所有item都会共享某一些属性。item中又可以包含Menu项,这是嵌套菜单(多级菜单)。
选项菜单
前面已经说到,选项菜单在3.0前后版本存在一些差别。在Fragment和Activity中都可以创建选项菜单,系统会首先显示Activity中创建的item,然后按照fragment加入的顺序添加item。在3.0一下时,onCreateOptionsMenu是在点击菜单键时触发;在3.0以上,则是在Activity创建时就会调用。
响应点击事件,可以在onOptionsItemSelected中进行。注意这个事件处理函数需要返回一个boolean值。如果已经处理了这次点击需要返回true,否则直接调用super.onOptionsItemSelected()(返回fasle)。这个事件的处理流程是,事件先被送到Activity,然后按照先进先达的顺序,直至莫一个fragement处理了这次点击或者所有的fragment都已经遍历了。
可以在菜单的item中指定android:onClick,这个点击事件的处理函数必须是Activity中签名为public 并且接受一个MenuItem的参数。
更新菜单中的选项,我们可以通过onCreateOptionsMenu来创建菜单项,但是如果想在运行时改变菜单中的选项,可以重写onPrepareOptionsMenu方法来实现。在3.0以下,这个方法会在菜单键每次按下的时候触发;在3.0以上,由于ActionBar是一直显示的,所以我们如果需要改变菜单,可以主动调用invalidateOptionsMenu(),然后系统会去走onPrepareOptionsMenu。
上下文菜单
Contextual Menu主要多用于和界面特别是AdapterView中的某一个item进行交互,通过长按控件来呼出一个Action Menu。如果说Option menu(Actionbar)上面的菜单选项是针对整个app的范围,那么Contextual Menu从名字就可以看出来是针对当前context范围内的操作。存在两种方式:
- floating context menu,通常在长按ListView中的某一项之后出现。
- Contextual action mode,会显示出一个ActionBar,它是一种ActionMode的实现,在3.0系统以上才能使用。
下图左边是floating context Menu,右边是Contextual action mode

floating context menu
floating context menu是3.0一下版本建议使用的,针对当前Context的一个操作面板,通过长按指定控件呼出。长按事件如果也被监听,那么会先执行长按事件,再执行onContextItemSelected。如果长按事件处理返回true,那么context Menu不会被呼出:
- 通过Activity或者Fragment的registerForContextMenu,传入一个View,为它注册一个floating context menu
- 实现onCreateContextMenu,来创建Menu条目
- 实现onContextItemSelected处理选择某一个菜单的事件
同样需要注意的是在处理事件时,也是由Activity最先接收,然后按照加入顺序分发到每一个Fragment。
contextual action mode
从上图可以看到Contextual action和ActionBar颇有几分相似,但是两者直接并无直接关联。在3.0一下版本中,我们需要使用support包中的兼容方案。
单个View使用步骤如下:
- 实现ActionMode.CallBack,这里主要实现action mode的主要逻辑
- 在合适的时候通过Activity或者fragment的startSupportActionMode来进入一个contextaul action mode。
在AdapterView中使用,步骤如下:
- 实现AbsListView.MultiChoiceModeListener,其实这个玩意继承自ActionMode.CallBack,增加了onItemCheckedStateChanged函数,用来处理当AbsListView中某一项的选择状态改变时的操作。
- 通过设置AbsListView的MultiChoiceModeListener,注意,这里默认进入Action Mode的动作是长按某一个Item。
Popup Menu
API level 11加入。在android中还提供了一种用来相对于界面上已经存在的一个控件的菜单,比如类似于ActionBar上面的overflow。

使用Popup Menu的步骤如下:
- 通过context和相对的View创建PopupMenu对象。
- 通过popupMenu对象来设置Menu的布局和监听事件函数。
需要注意的是PopupMenu弹出的位置是自适应的,主要看这个View在那个地方有空间,就会在哪个方向上面弹出来。
选择菜单项
选择菜单和前面所提及的菜单类型不同,它仅仅是一种菜单项的表现形式。在本文之前提及的所有菜单中,每一个菜单项的呈现方式都是简单的文字(或者icon),如果我们要加入一种单选框或者复选框的效果,可以使用item的checkable属性。效果如下图:

需要注意的是,在option Menu中,如果一个菜单项是以icon的方式显示出来,那么它将不会显示选择框。
我们亦可以通过group来为一组item设置选择条件,这才是它本来的意义。android:checkableBehavior可以设置成radio 或者checkbox或者none,默认应该是checkbox。
选择菜单项是不能保存状态的,如果app退出,下次再进入状态就不存在了。
意图菜单项
如果我们需要在菜单项中通过Intent启动另外一个Activity,Menu提供了专门的类型来处理,这就是Intent Options。而且意图菜单项还可以在系统中解析这个Intent是否能够被Activity了解,如果系统中没有Activity能够接受这个Intent,那么这个意图菜单项将不会展示出来。使用步骤如下:
- 在定义的Intent中增加一个category:
CATEGORY_ALTERNATIVE and/or CATEGORY_SELECTED_ALTERNATIVE - 调用Menu.addIntentOpions()。
addIntentOptions方法返回增加的item数目,所以通过Intent解析的item都会被加入菜单中。这个菜单项的item title就是intent-filter的android:label,icon是application icon
感觉这个东东和settings等系统模块一样,在中国开发者的眼中根本不会去用它,所以老外才会感叹中国做的app怎么这么难用,每个应用的风格都不一样。。。
Android中的菜单的更多相关文章
- android中常用菜单(menu)的基本知识
(一)选项菜单 1.简单的创建菜单: @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMe ...
- Android 中的菜单 OptionsMenu的简单应用
OptionsMenu就是安卓手机中的菜单选项 首先 要实现对菜单的操作就要先重写OnCreateOptionsMenu(Menu menu)方法 通常有两种方法来实现对菜单中选项的添加 第一种是动态 ...
- android中的菜单Menu
Menu是一个接口, 他有2个子接口, SubMenu和ContextMenu; 前者菜单常见于按home键就会出现 ,后者是一个上下文菜单, 一般点击某个条目会在手机屏幕中出现一个类似悬浮窗口的菜单 ...
- android中menu菜单的简单使用
我认为menu用起来简洁方便,特别是在一些大一点的程序中我们早就厌烦了一遍遍的加button,设置了菜单可谓是事半功倍,简单省事. <1>先声明定义下你的menu: private sta ...
- 关于android中,菜单按钮点击事件首次执行之后再次执行需要双击按钮的问题
有时候在获取事件的时候,需要双击才能获取,解决方法很简单,把返回值设为true,那么这个事件就不会再分发了,我预计是设为其他值会继续分发,造成事件的相应混乱
- 【转】Android菜单详解——理解android中的Menu--不错
原文网址:http://www.cnblogs.com/qingblog/archive/2012/06/08/2541709.html 前言 今天看了pro android 3中menu这一章,对A ...
- android中TabHost和RadioGroup
android底部菜单应用 博客分类: android--UI示例 TabHostMenuRadioGroupButton 在android中实现菜单功能有多种方法. Options Menu:用户 ...
- Android中的资源访问
Android中的资源是指非代码部分,指外部文件. assets中保存的一般是原生的文件,例如MP3文件,Android程序不能直接访问,必须通过AssetManager类以二进制流的形式来读取. r ...
- Android菜单详解(一)——理解android中的Menu
前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至 ...
随机推荐
- 惠普 hpacucli工具使用
命令组成 hpacucli [parameter=value] 查看: 查看所有控制器状态 hpacucli ctrl all show 查看slot 0阵列信息详细状态 (可以查看物理磁盘和逻辑磁 ...
- Python时间戳和日期
import time localtime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) prin ...
- (转)js 中{},[]中括号,大括号使用详解
一.{ } 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或是函数. 如:var LangShen = {"Name":"Langshen",&qu ...
- 学习在创建好的工程里面添加CoreData
在学习CoreData中, 在建工程后, 没有添加, 于是就参考网络文章进行更改. 这几天在学习做一个ios的小项目,项目中需要对数据进行基本的增删改查操作.于是就想用一把CoreData.但在创建项 ...
- 公众号的秘密,知道一个biz就够了
公众号的秘密,知道一个biz就够了 微信对于我来说,最有价值的是一个学习渠道,特别是搜狗微信搜索(http://weixin.sogou.com/)能够很方便的搜索公众账号和文章内容,PC端就能够获得 ...
- SQLServer分页
1.为什么要分页? 当显示数据的时候,我们不会一下子把所有的数据都显示出来,比如说表中有一万条数据,难道我们要把一万条数据都一次性的显示出来吗?!即便显示给用户了,用户也看不过来.因此,不论是从效率的 ...
- 浅谈JS中的闭包
浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...
- linux挂载查看、添加与取消
挂载概念: 查看挂载:df 添加挂载mount:mount 挂载的源 目的点 mount /dev/sdb1 /mnt mount挂载常用参数(Option) -t 指定文件系统类型,例如:-t ex ...
- 解决redis-cli连接时出现Could not connect to Redis at 127.0.0.1:6379: Connection refused
执行redis 配置文件 redis-server /etc/redis/redis.conf
- pyqt5猜数游戏
电脑随机生成4个互不相等的数,你猜. 1:你猜的数和正确答案相比,位置正确的个数 2:你猜的数虽然在正确答案中,但位置不对,它的个数. 代码如下: #!/usr/bin/env python # -* ...