【转】Pro Android学习笔记(三十):Menu(1):了解Menu
每个Activity都关联一个且是唯一一个menu对象,当对该menu进行创建,将触发onCreateOptionsMenu()。
创建Menu
我们通过下面简单的例子来阐述menu的各个属性。
public class OptionMenuTest extends Activity {
private static int MENU_GROUP_1 = 1;
private static int MENU_GROUP_2 = 2;
private Menu optionMenu = null;
... ...
@Override
// 一个Activity只关联一个menu,这使得处理比较简单,在onCreateOptionsMenu()中对menu进行具体的描述。返回true,确认menu为visible,否则menu不可视。
// 在Android3.0之前的版本,onCreateOptionsMenu()是在用户第一次访问option menu才调用,书中说在Android 3.0后,为了适配平板,menu是UI的一部分。onCreateOptionsMenu()是在Activity创建阶段调用。但是在实际实验中,对于手机,Android 4.0,仍是在第一次访问option menu中调用,可能平板和手机有不同的处理方式。
public boolean onCreateOptionsMenu(Menu menu) {
//menu.add(groupId, itemId, order, title); 通过add()增加menuItem,每个menuItem有groupId,itemId,Order。这三个属性是相互独立,没有关联。
menu.add(MENU_GROUP_1, 1, 1, "menuItem.1");
menu.add(MENU_GROUP_1, 2, 2, "menuItem.2");
menu.add(MENU_GROUP_2, 3, 3, "menuItem.3");
menu.add(MENU_GROUP_2, 4, 4, "menuItem.4");
optionMenu = menu; //获取menu对象,用于之后的试验
//只有返回true,才能显示menu,即menu为visible。如果设置false,则menu为invisible。
return true;
}
}
MenuItem的属性:itemId
MenuItem有三个关键的属性,groupId,itemId和Order。这三个属性是相互独立的,没有关联的。也就是不是有groupId和itemId共同作为itemId的表示,而只是由itemId作为menuItem的唯一标识,不能存在冲突。一般我们分配的itemId的为1~0x0ffff,在非常足够的。一般在程序中,我们并不如上例直接赋予itemId准确的数值,通常使用Menu.FIRST作为偏移量基准,如:
menu.add(MENU_GROUP_1, Menu.FIRST, 1, "menuItem.1");
menu.add(MENU_GROUP_1, Menu.FIRST + 1, 2, "menuItem.2");
menu.add(MENU_GROUP_2, Menu.FIRST + 2, 3, "menuItem.3");
menu.add(MENU_GROUP_2, Menu.FIRST + 3, 4, "menuItem.4");
Menu.FRIST为1,但我们不确定未来android版本会不会对之进行更改,采用相对偏移量是最安全的做法。
Android系统对itemId有分类:
- 0x10000(Menu.CATEGORY_CONTAINER)及之后的用于容器。例如layout就是一个容器。
- 0x20000(Menu.CATEGORY_SYSTEM)及之后的用于System,是系统预留的。Windows Phone平台有系统菜单项,如Close,Refresh;目前android系统并没有系统预留菜单项的定义,但有可能在未来增加。
- 0x30000(Menu.CATEGORY_SECONDARY)及之后的用于Sencondary,即相对不那么重要的。
- 0x40000(Menu.CATEGORY_ALTERNATIVE)及之后的用于alternative,由外部应用提供的替代方式。
MenuItem的itemId的唯一性是很容易保证的。如果我们通过XML,在资源中定义menu,具体例子见Pro Android学习笔记(十):了解Intent(上)中“系统的Intent”,系统会自动在R.java中分配唯一的id号。
MenuItem的属性:groupId
若干个itemId可以享有同一个groupId,通过groupId,可以对他们进行统一的操作。如下:
optionMenu.setGroupCheckable(MENU_GROUP_2, true /*isCheckable*/, false); //第三个参数true为单选,false为多选
optionMenu.setGroupEnabled(MENU_GROUP_2, false/*isEnabled*/);
optionMenu.setGroupVisible(MENU_GROUP_2, false /*isVisible*/);
optionMenu.removeGroup(MENU_GROUP_2);
MenuItem的属性:orderId
orderId决定item的排列顺序。在上面的例子中,如果我们将第三个item的orderId设置为6,如下:
menu.add(MENU_GROUP_2, 3, 6, "menuItem.3");
由于第四个item的orderId为4,小于第三个item的orderId,所以第四个item排在第三个之前。
MenuItem的属性:可选属性
groudId,itemId和orderId都是可选的属性,如果我们不需要进行区分,可以设置为Menu.NONE。
Menu触发
onOptionItemSelected
当用户点击menu item,将会触发onOptionItemSelected()回调函数,这是最常用的处理方式。
public booleanonOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){ //通过itemId判断具体是那个菜单项被用户点击
case 3:
case 4:
if(item.isCheckable()){ //如果我们设置了item为checkable,点击该菜单项,UI不会自动地显示选中,需要在代码中进行设置。
boolean isChecked = item.isChecked();
item.setChecked(!isChecked);
}
break;
default:
break;
}
// 菜单项点击,不仅提供onOptionsItemSelected()的一种触发方式,我们将在后面试验其他的两种方法,如果我们希望将菜单项点击的事件传递下去,继续触发其他处理,则返回false,如果我们认为全部已经处理完,到此为止,不需要将事件传递下去,则返回true。如果采用return super.onOptionsItemSelected(item); 则返回值为flase,即系统缺省返回false。
return true;
}
Click Listener
menu item同样支持click listener,但是这种方式在性能上没有onOptionItemSelected()节省,所以一般情况,我们仍会使用onOptionItemSelected()。但是click listener的优先级别比onOptionItemSelected()高,也就是菜单项点击后,先触发click listener,如果返回flase(未处理完,继续传递事件),才会进一步触发onOptionItemSelected()。
和所有的监听器一样,代码分为两步,一是注册监听器,二是编写监听器的回调函数。例如如下:
public class OptionMenuTest extends Activity implements OnMenuItemClickListener{
… …
@Override
public boolean onCreateOptionsMenu(Menu menu) {
… …
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) { // 优先级别低于onMenuItemClick()
... ...
//【步骤1】注册监听器
MenuItem item4 = menu.add(MENU_GROUP_2, 4, 4, "menuItem.4");
item4.setOnMenuItemClickListener(this);
… …
return super.onOptionsItemSelected(item);
}
@Override
//【步骤2】 实现监听器的回调函数,onMenuItemClickListener接口的onMenuItemClick()
public boolean onMenuItemClick(MenuItem item) {
……
return false; //如果返回true,chick事件将不往下传递,即不会触发onOptionsItemSelected();
}
}
使用Intent
将菜单项和intent关联,用户点击后,系统将自动执行startActivity(intent)。intent的优先级别低于onOptionItemSelected()。例在如下,当用户按菜单项1后,系统会打开browser,并打开指定的网页。
public boolean onCreateOptionsMenu(Menu menu) {
... ...
MenuItem item1 = menu.add(MENU_GROUP_1, 1, 1, "menuItem.1");
//关联intent,该intent会在执行完onOptionsItemSelected()后执行,当然onOptionsItemSelected()要返回false。
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://blog.csdn.net/flowingflying"));
item1.setIntent(intent);
... ...
return true;
}
相关链接: 我的Android开发相关文章
本博文涉及的例子代码,可以在Pro Android学习:Menu中下载。
【转】Pro Android学习笔记(三十):Menu(1):了解Menu的更多相关文章
- 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView
目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...
- 【转】Pro Android学习笔记(十二):了解Intent(下)
解析Intent,寻找匹配Activity 如果给出component名字(包名.类名)是explicit intent,否则是implicit intent.对于explicit intent,关键 ...
- 【转】Pro Android学习笔记(十):了解Intent(上)
目录(?)[-] Intent基本含义 系统的Intent Android引入了Intent的概念来唤起components,component包括:1.Activity(UI元件) 2.Servic ...
- 【转】Pro Android学习笔记(十四):用户界面和控制(2):Text类控制
目录(?)[-] TextView 例子1在XML中设置autoLink属性 例子2在代码中设置autoLink属性 EditText AutoCompleteTextView MultiAutoCo ...
- 【转】Pro Android学习笔记(十六):用户界面和控制(4):ImageView控件
目录(?)[-] XML片段 代码设置ImageView ImageView是基础的控件,它是android.widget.ImageView的继承类. XML片段 <LinearLa ...
- 【转】Pro Android学习笔记(十八):用户界面和控制(6):Adapter和AdapterView
目录(?)[-] SimpleCursorAdapter 系统预置的layout ArrayAdapter 动态数据增插删排序 自定义TextView风格 其他Adapter AdapterView不 ...
- 【转】Pro Android学习笔记(十五):用户界面和控制(3):Button控件
目录(?)[-] 基础Button ImageButton ToggleButton CheckBox RadioButton 基础Button Button是最常用的基础控件之一,在Android中 ...
- 【转】 Pro Android学习笔记(三五):Menu(6):XML方式 & PopUp菜单
目录(?)[-] 利用XML创建菜单 XML的有关属性 onClick事件 Pop-up菜单 利用XML创建菜单 在代码中对每个菜单项进行设置,繁琐且修改不灵活,不能适配多国语言的要求,可以利用资源进 ...
- 【转】Pro Android学习笔记(二五):用户界面和控制(13):LinearLayout和TableLayout
目录(?)[-] 布局Layout 线性布局LinearLayout 表格布局TableLayout 布局Layout Layout是容器,用于对所包含的view进行布局.layout是view的子类 ...
随机推荐
- 我的Android进阶之旅------>Android中AsyncTask源码分析
在我的<我的Android进阶之旅------>android异步加载图片显示,并且对图片进行缓存实例>文章中,先后使用了Handler和AsyncTask两种方式实现异步任务机制. ...
- python元组和列表区别
元组可以简单认为是一个只读的列表 tuper = const list
- selenium鼠标悬停操作
有些网页一打开会有一个弹窗,弹窗不消失无法进行取元素操作,只有把鼠标悬停在上面弹窗才会消失,这时就用到了selenium的悬停操作 鼠标悬停 move_to_element() 定位到要悬停的元素 ...
- 【八】MongoDB管理之分片集群实践
MongoDB中集群有三种:主从复制.副本集.分片集群.目前副本集已经替代主从复制架构,成为官方建议采用的架构,而分片集群相较于前两种,更加复杂. 下面是生产环境中常用的分片集群架构: 我们知道,分片 ...
- P4022 [CTSC2012]熟悉的文章
题目 P4022 [CTSC2012]熟悉的文章 题目大意:多个文本串,多个匹配串,我们求\(L\),\(L\)指(匹配串中\(≥L\)长度的子串出现在文本串才为"熟悉",使得匹配 ...
- Docker 数据管理-Volumes
Volumes是Docker最为推荐的数据持久化方法. Volumes have several advantages over bind mounts: Volumes are easier to ...
- keepalvied虚拟ip安装设置
keepalvied 虚拟ip 第一步:主服务器上设置虚拟ip (也可以不设置虚拟ip,keepalived启动的时候会自动设置) ifconfig ens33:1 192.168.136.131 n ...
- 算法(Algorithms)第4版 练习 1.5.6
对于weighted quick-union,对每个输入数据对,其最大的循环次数为lgN(sites) 故对于109 sites和106 input pairs,其总的指令次数为:sum = lg10 ...
- Storm 执行异常 java.lang.RuntimeException: java.nio.channels.UnresolvedAddressException 问题解决
最近写的 binlog2kafka storm job 上线在一个新的集群环境中(storm 0.9.0.1, kafka 0.8), storm job 运行时报出如下异常: java.lang.R ...
- 大话设计模式--外观模式 Facade -- C++实现实例
1. 外观模式: 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这个子系统更加容易使用. 外观模式的使用场合: A: 设计初期阶段,应该要有意识的将不同的两个层分离. ...