Android的简述2
android提供了三种菜单类型,分别为options menu,context menu,sub menu。
options menu就是通过按home键来显示,context menu需要在view上按上2s后显示。这两种menu都有可以加入子菜单,子菜单不能种不能嵌套子菜单。options menu最多只能在屏幕最下面显示6个菜单选项,称为iconmenu,icon menu不能有checkable选项。多于6的菜单项会以more icon menu来调出,称为expanded menu。options menu通过activity的onCreateOptionsMenu来生成,这个函数只会在menu第一次生成时调用。任何想改变options menu的想法只能在onPrepareOptionsMenu来实现,这个函数会在menu显示前调用。onOptionsItemSelected 用来处理选中的菜单项。
context menu是跟某个具体的view绑定在一起,在activity种用registerForContextMenu来为某个view注册context menu。context menu在显示前都会调用onCreateContextMenu来生成menu。onContextItemSelected用来处理选中的菜单项。
android还提供了对菜单项进行分组的功能,可以把相似功能的菜单项分成同一个组,这样就可以通过调用setGroupCheckable,setGroupEnabled,setGroupVisible来设置菜单属性,而无须单独设置。
Options Menu
Notepad中使用了options menu和context menu两种菜单。首先来看生成options menu的onCreateOptionsMenu函数。
menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert)
.setShortcut('3', 'a')
.setIcon(android.R.drawable.ic_menu_add);
这是一个标准的插入一个菜单项的方法,菜单项的id为MENU_ITEM_INSERT。有意思的是下面这几句代码:
Intent intent = new Intent(null, getIntent().getData());
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
new ComponentName(this, NotesList.class), null, intent, 0, null);
这到底有何用处呢?其实这是一种动态菜单技术(也有点像插件机制),若某一个activity,其类型是”android.intent.category.ALTERNATIVE”,数据是”vnd.android.cursor.dir/vnd.google.note”的话,系统就会为这个activity增加一个菜单项。在androidmanfest.xml中查看后发现,没有一个activity符合条件,所以这段代码并没有动态添加出任何一个菜单项。
为了验证上述分析,我们可以来做一个实验,在androidmanfest.xml中进行修改,看是否会动态生成出菜单项。
实验一
首先我们来创建一个新的activity作为目标activity,名为HelloAndroid,没有什么功能,就是显示一个界面。
public class HelloAndroid extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
}
}
它所对应的布局界面XML文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="@+id/TextView01"/> <Button android:id="@+id/Button01" android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="@string/txtInfo"></Button>
</LinearLayout>
然后修改androidmanfest.xml,加入下面这段配置,让HelloAndroid满足上述两个条件:
<activity android:name="HelloAndroid" android:label="@string/txtInfo">
<intent-filter>
<action android:name="com.android.notepad.action.HELLO_TEST" />
<category android:name="android.intent.category.ALTERNATIVE"/>
<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>
</activity>
好了,运行下试试,哎,还是没有动态菜单项加入呀!怎么回事呢?查看代码后发现,原来是onPrepareOptionsMenu搞的鬼!这个函数在onCreateOptionsMenu之后运行,下面这段代码中,由于Menu.CATEGORY_ALTERNATIVE是指向同一个组,所以把onCreateOptionsMenu中设置的菜单项给覆盖掉了,而由于onPrepareOptionsMenu没有给Menu.CATEGORY_ALTERNATIVE附新值,故Menu.CATEGORY_ALTERNATIVE还是为空。
Intent intent = new Intent(null, uri);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,items);
好的,那我们暂时把上面这几句给注释掉,当然,也可以不注释这几句,在onCreateOptionsMenu中改groupid号,即将Menu.CATEGORY_ALTERNATIVE改为Menu.first,其他的也行,但注意不要改为menu.none,这样会覆盖掉。
menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert)
.setShortcut('3', 'a')
.setIcon(android.R.drawable.ic_menu_add);
添加的菜单。因为menu.none也为0。运行后就可以看到动态菜单出来了!
上面这个options menu是在NotesList界面上没有日志列表选中的情况下生成的,若先选中一个日志,然后再点”menu”,则生成的options menu是下面这样的:
哎,又动态增加了两个菜单项”Edit note”和”Edit title”,这又是如何动态加入的呢?这就是onPrepareOptionsMenu的功劳了。
Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId());
首先获取选中的日志(若没有选择,则uri为空)
Intent[] specifics = new Intent[1];
specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
MenuItem[] items = new MenuItem[1];
然后为选中的日志创建一个intent,操作类型为Intent.ACTION_EDIT,数据为选中日志的URI.于是会为选中的日志创建一个”Edit note”菜单项。
Intent intent = new Intent(null, uri);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,
items);
这几句和上面onCreateOptionsMenu函数中类似,用于动态增加菜单项,若某一个activity,其类型是”android.intent.category.ALTERNATIVE”,数据是”vnd.android.cursor.item/vnd.google.note”的话,系统就会为这个activity增加一个菜单项。在androidmanfest.xml中查看后发现,TitleEditor这个activity符合条件,于是系统就为TitleEditor这个activity动态添加一个菜单项”Edit title”。
else {
menu.removeGroup(Menu.CATEGORY_ALTERNATIVE);
}
若日志列表为空,则从菜单中删除组号为Menu.CATEGORY_ALTERNATIVE的菜单项,只剩下”Add note”菜单项。
处理“选中菜单项”事件
菜单项选中事件的处理非常简单,通过onOptionsItemSelected来完成,这里只是简单地调用 startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));这个intent的操作类型为Intent.ACTION_INSERT,数据为日志列表的URI,即”content:// com.google.provider.NotePad/notes”
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ITEM_INSERT:
// Launch activity to insert a new item
startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
return true;
}
return super.onOptionsItemSelected(item);
}
Context Menu
下面介绍另一种菜单---上下文菜单,这通过重载onCreateContextMenu函数实现。首先确认已经选中了日志列表中的一个日志,若没选择,则直接返回。Cursor指向选中的日志项。
Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
if (cursor == null) {
// For some reason the requested item isn't available, do nothing
return;
}
然后,设置上下文菜单的标题为日志标题
// Setup the menu header
menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
最后为上下文菜单增加一个菜单项
// Add a menu item to delete the note
menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_delete);
对于上下文菜单项选中的事件处理,是通过重载onContextItemSelected实现的。
switch (item.getItemId()) {
case MENU_ITEM_DELETE: {
// Delete the note that the context menu is for
Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
getContentResolver().delete(noteUri, null, null);
return true;
}
}
return false;
}
对于日志的删除,首先调用ContentUris.withAppendedId(getIntent().getData(), info.id);来拼接出待删除日志的URI.然后getContentResolver().delete(noteUri, null, null);调用下层的Content Provider去删除此日志。
实验二
来做个简单实验,在上述代码基础上增加一个上下文菜单项。首先在onCreateContextMenu函数中增加一个上下文菜单项:
menu.add(0,MENU_ITEM_INSERT,0,R.string.menu_insert);
然后为其在onContextItemSelected函数中增加一个处理过程:
case MENU_ITEM_INSERT:
{
new AlertDialog.Builder(this).setIcon(R.drawable.app_notes)
.setTitle(R.string.app_name).setMessage(R.string.error_message).setPositiveButton(R.string.button_ok, new OnClickListener(){ public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).show();
return true;
}
实验结果如下:
Android的简述2的更多相关文章
- Android Animation简述
Android Animation简述 一.动画(Animation) Android框架提供了两种动画系统:属性动画(Android3.0)和视图动画.同时使用两种动画是可行的,但 ...
- 学习笔记-- android动画简述
android支持三种类型的动画: ·属性动画 一种补间动画,通过在目标对象的任何属性的两个值之间应用赠了变化,可以生成一种动画效果.这种动画可以用来生成各种效果,例如:改变视图的颜色.透明条.淡入 ...
- Android字体简述
Android是一个典型的Linux内核的操作系统.在Android系统中,主要有DroidSans和DroidSerif两大字体阵营,从名字就可以看出来,前者是无衬线字体,后者是衬线字体.具体来说, ...
- Android的简述4
NoteEditor深入分析 首先来弄清楚“日志编辑“的状态转换,通过上篇文章的方法来做下面这样一个实验,首先进入“日志编辑“时会触发onCreate和onResume,然后用户通过Option Me ...
- Android的简述3
Activity的生命周期 Activity类中有许多onXXX形式的函数可以重载,比如onCreate,onStart,onStop,onPause,那么它们的调用顺序到底是如何的呢?下面就通过一个 ...
- Android的简述
程序截图 先来简单了解下程序运行的效果 程序入口点 类似于win32程序里的WinMain函数,Android自然也有它的程序入口点.它通过在AndroidManifest.xml文件中配置来指明, ...
- Android SDK自带调试优化工具
Android sdk中自带了一些分析内存,界面调优的非常实用的工具,这对于分析和调试我们的应用十分有帮助,由于我使用的是linux版本的sdk,所以就以linux版本的工具做一个介绍,这些工具的具体 ...
- Android网络定位服务定制简述
Android 添加高德或百度网络定位服务 Android的网络定位服务以第三方的APK方式提供服务,由于在国内Android原生自带的com.google.android.gms服务几乎处于不可用状 ...
- Android开发3:Intent、Bundle的使用和ListView的应用 、RelativeLayout(相对布局)简述(简单通讯录的实现)
前言 啦啦啦~博主又来骚扰大家啦~大家是不是感觉上次的Android开发博文有点长呢~主要是因为博主也是小白,在做实验的过程中查询了很多很多概念,努力去理解每一个知识点,才完成了最终的实验.还有就是随 ...
随机推荐
- Django的的安装和配置
1. 下载 1. 命令行 pip install django==1.11.18 -i https://pypi.douban.com/simple/ 2. 创建项目 1. 命令行 django-ad ...
- Hive 学习之路(六)—— Hive 视图和索引
一.视图 1.1 简介 Hive 中的视图和RDBMS中视图的概念一致,都是一组数据的逻辑表示,本质上就是一条SELECT语句的结果集.视图是纯粹的逻辑对象,没有关联的存储(Hive 3.0.0引入的 ...
- spring 5.x 系列第11篇 —— 整合memcached (xml配置方式)
文章目录 一.说明 1.1 XMemcached客户端说明 1.2 项目结构说明 1.3 依赖说明 二.spring 整合 memcached 2.1 单机配置 2.2 集群配置 2.3 存储基本类型 ...
- Spring事物管理简介 (转)
一.事物1.什么是事物 事物指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败 2.事物的特性 原子性:事物是一个不可分割的工作单位,事物中的操作要么都发生,要么都不发生 一致性:事物前后数据 ...
- TCP/IP 第一章
1,tcp/ip协议族作用:连接互联网中的计算机,并使其通信.可以想象互联网的计算机有不同的操作系统,如linux.unix.bsd.srv.windows.mac等.这么多操作系统对tcp/ip的实 ...
- java虚拟机-GC-GC算法
在C/C++中是由程序员自己去申请.管理和释放内存的,因此没有GC的概念.而在Java中,专门有一个用于垃圾回收的后台线程来进行监控.扫描,自动将一些无用的内存进行释放.下面介绍几种常见的GC算法. ...
- Codeforces 305B:Continued Fractions(思维+gcd)
http://codeforces.com/problemset/problem/305/B 题意:就是判断 p / q 等不等于那条式子算出来的值. 思路:一开始看到 1e18 的数据想了好久还是不 ...
- HDU 5792:World is Exploding(树状数组求逆序对)
http://acm.hdu.edu.cn/showproblem.php?pid=5792 World is Exploding Problem Description Given a sequ ...
- 设计模式:代理模式是什么,Spring AOP还和它有关系?
接着学习设计模式系列,今天讲解的是代理模式. 定义 什么是代理模式? 代理模式,也叫委托模式,其定义是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用.它包含了三个角色: Subject: ...
- .Net Core 通用主机(Core 在控制台应用程序中的应用)
一.介绍 官方文档中说,Microsoft.AspNetCore.App 元包(ASP.NET Core 2.1 或更高版本)包含通用主机的Microsoft.Extensions.Hosting包, ...