Pro Android学习笔记(三三):Menu(4):Alternative菜单

什么是Alternative menu(替代菜单)

举个例子,Activity显示一个文本文件。如果用户想对文本文件进行编辑,Activity不提供编辑能力,但可由其他activity或者其他应用提供。我们将相关信息存储在一个intent中,例如该文本的Uri。这个intent可以匹配系统的多个应用,替代菜单将这些应用一一列出,菜单项的title就是该可被调用的activity的名字,图标也为该可被调用的activity的图表。

小例子说明

我们通过一个小例子进行学习,简单地打开一个URL:wei://flowingflying/helloworld。在之前Intent的学习中,我们通过schema的配置,匹配该URL,也就是我们已经有其他应用的Activity(Intent Basic Test)可以打开该URL。我们同时在App中新增一个activity也能打开该URL。这样,将在alternative菜单中加入两个菜单项,点击它们,将打开相应的activity,并通过intent传递相关的数据信息。

新增的acitivity名字为Invoke Action(好像应该是invoked才对,不好意思)。在AndroidManifest.xml中加入intent-fliter的描述即可,具体见:Pro Android学习笔记(十一):了解Intent(中) 。

<activity android:name=".InvokeAction" android:label="@string/invokeAction" android:icon="@drawable/leaf" >
    <intent-filter > 
        <action android:name="android.intent.action.VIEW" /> 
        <data android:scheme="wei" /> 
        <category android:name="android.intent.category.DEFAULT" /> 
        <category android:name="android.intent.category.ALTERNATIVE" /><!-- 将在最后讨论 -->
    </intent-filter> 
</activity> 

Alternative menu代码

我们看看如何将替代菜单加入到OptionMenu中。Alternative menu还可以加载subMenu,Context Menu中。

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // 对比:加入一个普通菜单项  
    menu.add("普通菜单项");  

    //【步骤1】设置intent,本例简单实用一个已知的Uri。
    Intent menuIntent = new Intent(null,Uri.parse("wei://flowingflying/helloWorld")); 

    //【步骤2】加入Alternative菜单。在之前的Item ID类别中已经讲过,Android对ID进行了划分,有alternative的ID范围。
    int menuGroup = Menu.CATEGORY_ALTERNATIVE; 
    int startingItemId = Menu.CATEGORY_ALTERNATIVE
    int orderId = Menu.CATEGORY_ALTERNATIVE;  
    menu.addIntentOptions(  //返回增加的菜单项数目,本例为2
            menuGroup,  /* int groupId */ 
            startingItemId,  /* int itemId:由于自动跳转到,此参数可以设置为Menu.NONE。 */
            orderId,   /*int order*/ 
            this.getComponentName(), /* ComponentName caller:当前的activity名字,这是android系统处理alternatice menu是调用的queryIntentActivityOptions()函数所需要的参数。getComponentName()返回package名字和class名字,系统以此获知源activity是谁。 */
            null,  /* Intent[] specifics:匹配可能有多个intent,此用于过滤,但具体用途不详 */
            menuIntent,  /* Intent intent:关键的intent */
            0,  /* flages:关于items如何加入。0表示 no flag*/
            null);  /* MenuItem[] outSpecificItems ,与specifice相关*/

    return super.onCreateOptionsMenu(menu); 

关于Category和规范代码写法

我们注意到,在被唤起的actvity中有下面的描述:

[html] view plaincopy
  1. <category android:name="android.intent.category.ALTERNATIVE" />  

在试验中,发现此项可有可无,并不真正影响结果。而在reference中却明确表示要为CATEGORY_ALTERNATIVE或者CATEGORY_SELECTED_ALTERNATIVE。为何?

我们以Alternative menu的方式调用其他activity,正规的做法是,被唤起的activity应允许被alternative菜单唤起。因此被唤起的activity在intent-fliter中需给出类别。同时alternative菜单的intent也应当标明自己类型。因此规范的代码是:

Intent menuIntent = new Intent(null,this.getIntent().getData()); 
menuIntent.addCategory(Intent.CATEGORY_ALTERNATIVE); 

在小例子中,由于其他应用的Activity(Intent Basic Test)在Manifest XML中并没有给出相应的类别,不被匹配。运行结果如图:

关于flags

menu.addIntentOptions()的倒数第二个参数是flags,表示菜单项添加的方式。0,即缺省,表示如果groupId相同,则替代菜单将取代原有的菜单项设置。如果我们想保留原有的同一Group的菜单项,可以将flags设置为Menu.FLAG_APPEND_TO_GROUP。注意,如果groupId为Menu.NONE是不进行替换的,这个表示不设置GroupId,并非GroupId为0。

多个匹配的itemId等参数

让我们看看系统是如何实现Alternative菜单的。从reference中看到,Menu是一个interface,具体是通过MenuBuilder实现(源代码见android-17(version)/com/android/internal/view/menu/MenuBuilder.java。相关代码如下:

public int addIntentOptions(int group, int id, int categoryOrder, ComponentName caller,
        Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) {
    PackageManager pm = mContext.getPackageManager(); 
    final List<ResolveInfo> lri =  //查询匹配的Activity信息 
            pm.queryIntentActivityOptions(caller, specifics, intent, 0); 
    final int N = lri != null ? lri.size() : 0;
    //下面说明如果flag表示FLAG_APPEND_TO_GROUP,会删除整个group,取而代之
    if ((flags & FLAG_APPEND_TO_GROUP) == 0) { 
        removeGroup(group); 
    } 

    for (int i=0; i<N; i++) { 
        final ResolveInfo ri = lri.get(i); 
        Intent rintent = new Intent( 
            ri.specificIndex < 0 ? intent : specifics[ri.specificIndex]); 
        rintent.setComponent(new ComponentName( 
                ri.activityInfo.applicationInfo.packageName, 
                ri.activityInfo.name)); 
        final MenuItem item = add(group, id, categoryOrder, ri.loadLabel(pm))
                .setIcon(ri.loadIcon(pm)) 
                .setIntent(rintent);
 
        if (outSpecificItems != null && ri.specificIndex >= 0) {
            outSpecificItems[ri.specificIndex] = item; 
        } 
    } 

    return N; 

从源代码,可能看出如果有多个匹配,这些菜单项具有相同的group,相同的id,和相同categoryOrder。虽然我们在小例子中使用了startingItemId,但是实际上itemId是相同的。在小例子中,我们增加了public boolean onOptionsItemSelected(MenuItem item),并在里面检查item的参数值,证实确实相同。

这段代码还说明了菜单项的名字和图片为何,以及为何能唤起Activity。采用了setIntent(),是在Pro Android学习笔记(三十):Menu(1):了解Menu学习过的的一种触发机制。

本博文涉及的例子代码,可以在Pro Android学习:Menu中下载。

转载于:https://www.cnblogs.com/mzsoft/p/4467780.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574615.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java实现手机开关机_Android 系统重启与关机:Java 代码实现

粘贴一篇关于权限的文章&#xff1a;最近在做个东西&#xff0c;巧合碰到了sharedUserId 的问题&#xff0c;所以收集了一些资料&#xff0c;存存档备份。安装在设备中的每一个apk文件&#xff0c;Android 给每个 APK 进程分配一个单独的用户空间,其 manifest 中的 userid 就是…

C# 泛型的协变和逆变

1. 可变性的类型&#xff1a;协变性和逆变性 可变性是以一种类型安全的方式&#xff0c;将一个对象当做另一个对象来使用。如果不能将一个类型替换为另一个类型&#xff0c;那么这个类型就称之为&#xff1a;不变量。协变和逆变是两个相互对立的概念&#xff1a; 如果某个返回的…

java数据类型的站位_Java 数据类型在实际开发中应用

在前边的文章中&#xff0c;我已经介绍了Java核心的容器IO等&#xff0c;现在我来说一下java中的数据类型。在java中&#xff0c;一切东西皆为对象(这句话意思是java中绝大数情况都用对象)&#xff0c;极少数不是对象的&#xff0c;也存在与之对应的对象(比如基本数据类型存在与…

块状元素的居中,首先设置宽度,再设 margin: 0 auto

块状元素的居中&#xff0c;首先设置宽度 width"10px"&#xff0c;再设 margin: 0 auto; 。转载于:https://www.cnblogs.com/npk19195global/p/4475576.html

java amf3_Java AMF3 反序列化漏洞分析

写在前面的话AMF(Action Message Format)是一种二进制序列化格式&#xff0c;之前主要是Flash应用程序在使用这种格式。近期&#xff0c;Code White发现有多个Java AMF库中存在目前&#xff0c;漏洞相关信息已上报至美国CERT(详情请参考美国CERT VU#307983)概述目前&#xff0c…

typecho除了首页其他大部分网页404怎么办?

server {listen 80;server_name blog.localhost; #绑定域名index index.htm index.html index.php; #默认文件root /data/webroot/blog; #网站根目录location ~ \.php$ {fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;include fastcgi_params;}if (-f $request_filenam…

java能写复杂的查询么_spring-data-jpa 复杂查询的写法(包含or的查询)

场景如下&#xff1a;很简单的CMS常用查询&#xff0c;栏目下有多个子栏目&#xff0c;子栏目有包含内容。public class Channel{....private String parentIds;//所有的父节点&#xff0c;简化查询策略 例如 0,1,11,private List channels Lists.newArrayList(); //所有的儿子…

在Ubuntu上安装misterhouse

配置Ubuntu 您将对Ubuntu的配置做某些微小更改以便远程管理MH BOX和安装Misterhouse正常运行所需的必要的软件模块。首先要进行系统升级。因为系统提供的欧洲源更新实在是太慢了&#xff01;更换源是为了节省时间&#xff0c;尽快得将系统更新一遍。安装完系统后这是重要的一个…

java+路径拦截实现_SpringBoot实现拦截器

首先&#xff0c;你的项目要能跑起来&#xff0c;且基于springboot的boot的拦截器不用配置web.xml&#xff0c;按照特定名字书写(后缀注解)&#xff0c;它会自动识别(位置随便放&#xff0c;只要在代码目录下就可以)1.拦截器 SessionInterceptor.javapackage com.hfanss.blog.u…

Codeforces 524C Idempotent functions

题目链接&#xff1a;http://codeforces.com/problemset/problem/542/C 题目大意&#xff1a;给定一种运算f&#xff0c;对于输入的数组来说&#xff0c;一步操作&#xff0c;f(x) a[x]&#xff0c;两步操作&#xff0c;f^2(x) a[a[x]]....倘若每次进行k步操作之后&#xff0…

c 获取mysql安装路径_linux查看mysql安装路径

Linux下查看mysql、apache是否安装,并卸载。指令 ps -ef|grep mysql 得出结果root 17659 1 0 2011 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir/var/lib/mysql --socket/var/lib/mysql/mysql.sock --log-error/var/log/mysqld.log --pid-file/var/run/mysqld/mysqld.p…

微信JS-SDK

<div class"lbox_close wxapi_form"><h3 id"menu-basic">基础接口</h3><span class"desc">判断当前客户端是否支持指定JS接口</span><button class"btn btn_primary" id"checkJsApi">c…

java exif 语言编码_Java读取图片EXIF信息的代码

Java读取图片EXIF信息的代码本文实例讲述了Java读取图片EXIF信息的方法。分享给大家供大家参考。具体分析如下&#xff1a;首先介绍一下什么是EXIF&#xff0c;EXIF是Exchangeable Image File的缩写&#xff0c;这是一种专门为数码相机照片设定的格式。这种格式可以用来记录数字…

Java和pathion_Spring配置中的classpath:与classpath*:的区别

概念解释及使用场景&#xff1a;classpath是指WEB-INF文件夹下的classes目录。通常我们一般使用这种写法实在web.xml中&#xff0c;比如spring加载bean的上下文时&#xff0c;如下&#xff1a;contextConfigLocationclasspath*:/spring-context-*.xmlorg.springframework.web.c…

PHP单引号 ' ',没有任何意义,对所引内容不经任何处理直接拿过来

单引号 没有任何意义&#xff0c;对单引号内部内容不经任何处理直接拿过来。转载于:https://www.cnblogs.com/npk19195global/p/4490758.html

UILabel 宽高自适应

在iOS中&#xff0c;经常遇到需要根据字符串的内容动态指定UILabel&#xff0c;UITextView,UITableViewCell等的高度的情况&#xff0c;这个时候就需要动态的计算字符串内容的高度&#xff0c;下面是计算的方法&#xff1a; /** method 获取指定宽度情况ixa&#xff0c;字符串…

php debug build no,php – 尝试安装xdebug:找不到配置文件

我按照这些说明下载xdebug&#xff1a;http://xdebug.org/wizard.php.向导的输出是这样的&#xff1a;SummaryXdebug installed: noServer API: Apache 2.0 HandlerWindows: noZend Server: noPHP Version: 5.4.17Zend API nr: 220100525PHP API nr: 20100525Debug Build: noTh…

自动自发

<自动自发> 第1章 序言 你属于哪种人&#xff1f; 我们经常会听到这些熟悉的话语&#xff1a; “现在是午餐时间&#xff0c;请您3点以后再打过来吧。” “那根本就不是我负责的工作。” “我现在很忙。” “那是汉曼的工作。” “我不知道该怎样帮助你。” “你去图书馆…

php修改js内容,js怎样修改html元素的内容?HTML DOM实现修改内容

js怎样修改html元素的内容&#xff1f;本章就给大家介绍在js中利用HTML DOM是怎样修改html元素内容的。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对你们有所帮助。首先我们要了解HTML DOM是什么&#xff1f;HTML DOM的作用是什么&#xff1f;HTML…

java中的删除函数的使用方法,如何用Java删除文件

本文概述有两种删除Java文件的方法&#xff1a;使用File.delete()方法使用File.deleteOnExit()方法Java File.delete()方法在Java中, 我们可以使用File类的File.delete()方法删除文件。 delete()方法删除由抽象路径名表示的文件或目录。如果路径名是目录, 则该目录必须为空才能…