- 浏览: 875311 次
- 性别:
- 来自: 北京
最新评论
-
luna_2006:
...
【Java】枚举类型Enum介绍和方法详解 -
沙漠孤影:
...
【Android】Android Market 链接的生成与分享 -
sjl_008:
有错误,inSampleSize 为2时,图片大小不是原来的2 ...
【Android】如何解决bitmap 内存溢出out of memory的问题 -
huanglei_jay:
【Java】Collections.EMPTY_LIST和Collections.emptyList()简单使用心得 -
wuxuewujiang:
很详细!很有用的整理。
【Objective-C】NSDate详解及获取当前时间等常用操作
转自:http://blog.csdn.net/silenceburn/article/details/6069988
作者:silenceburn
Activity的setDefaultKeyMode (int mode) 方法用来设置一个Activity的默认的按键模式。
具体介绍可以参见我写的 setDefaultKeyMode 用法介绍 一文。
地址是: http://blog.csdn.net/silenceburn/archive/2010/12/11/6069645.aspx
其中有一种模式是 DEFAULT_KEYS_SHORTCUT ,本文从API文档对此模式的介绍出发,
首先通过编写示例代码,介绍其功能用法,然后通过追踪源码,简单介绍此模式在android源码中是如何实现的。
1. 关于 DEFAULT_KEYS_SHORTCUT 的 API文档介绍
Use with setDefaultKeyMode(int) to execute a menu shortcut in default key handling.
That is, the user does not need to hold down the menu key to execute menu shortcuts.
从字面上看,其含义是指,将默认的按键输入作为菜单快捷键进行处理。
也就是说,用户不需要按下menu按键,就可以处理菜单快捷键,听起来非常神奇,究竟是不是这样呢?
2.编写示例程序
我们编写一个程序验证一下其功能,首先新建一个工程,并设置默认按键模式为 DEFAULT_KEYS_SHORTCUT
- package com.silenceburn;
- import android.app.Activity;
- import android.os.Bundle;
- public class MenuShortCutTester extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
- }
- }
为默认的main.xml中的TextView增加一个id属性,之后我们会用菜单选项控制这行字的颜色
- <?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:id="@+id/myText"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- </LinearLayout>
使用findViewById获取上一步中定义了id的文本对象,将其引用保存在成员变量b中。
重写onPrepareOptionsMenu方法,增加我们自己的菜单项,并注册快捷键,同时增加菜单点击的响应事件。
- package com.silenceburn;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.MenuItem.OnMenuItemClickListener;
- import android.widget.TextView;
- public class MenuShortCutTester extends Activity {
- /** Called when the activity is first created. */
- TextView b;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- b = (TextView) this.findViewById(R.id.myText);
- setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
- }
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- // TODO Auto-generated method stub
- super.onPrepareOptionsMenu(menu);
- menu.removeItem(0);
- menu.removeItem(1);
- menu.add( 0, 0, 0, "One").setShortcut('0', '0').setOnMenuItemClickListener(new OnMenuItemClickListener(){
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- // TODO Auto-generated method stub
- b.setBackgroundColor(android.graphics.Color.RED);
- return true;
- }});
- menu.add( 0, 1, 0, "Two").setShortcut('1', '1').setOnMenuItemClickListener(new OnMenuItemClickListener(){
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- // TODO Auto-generated method stub
- b.setBackgroundColor(android.graphics.Color.GREEN);
- return true;
- }});
- return true;
- }
- }
注意我们一共注册了两个菜单项,
一个叫“One”,点击时将文本对象 b 的背景颜色改为红色,同时定义其快捷键为0
一个叫“Two”,点击时将文本对象 b 的背景颜色改为绿色,同时定义其快捷键为1
至此示例程序完成。
3.验证使用示例程序
启动AVD,运行上述程序,程序启动后,我们应当看到是黑底灰字,点击menu按钮,可以看到One和Two两个菜单选项。
如下图所示:
目前Menu是打开状态,
点击One ,将把“helloworld...”字样的背景色变为红色,
点击Two ,将把“helloworld...”字样的背景色变为红绿色。
或者我们点设置好的快捷键 0 和 1,发现可以直接调用菜单选项控制颜色变化。
到目前为止一切都很正常,不过,神奇的现在来了!
我们首先关闭菜单,
然后直接点键盘键"0“,看看会发生什么。再直接点键盘键"1" ,看看会发生什么。
哈哈,在没有激活菜单的情况下,菜单项快捷键被直接调用了!根本不需要打开菜单,就可以用激活菜单快捷键!
什么?有位同学说快捷键就应该是这样子把,那好,请你把 onCreate 里面的
setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); 改为 setDefaultKeyMode(DEFAULT_KEYS_DISABLE);
然后再运行试试,在不打开菜单的情况下,你就是把 0 和 1 按坏,系统也不会理你的呵呵
4.浅析实现原理
那么这神奇的功能是如何实现的呢?我们试着通过分析android源码找到答案。
首先顺藤摸瓜,我们找一找系统是如何处理 DEFAULT_KEYS_SHORTCUT 关键字的,
在Activity.java中可以找到如下代码片段:
- if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) {
- return false;
- } else if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) {
- if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL,
- keyCode, event, Menu.FLAG_ALWAYS_PERFORM_CLOSE)) {
- return true;
- }
- return false;
- }
由此可知,当系统检测到 DEFAULT_KEYS_SHORTCUT 关键字时,实际调用了
getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL,
keyCode, event,Menu.FLAG_ALWAYS_PERFORM_CLOSE)
我们继续追寻,但是这里会遇到一个困难,就是查阅API文档你会发现,performPanelShortcut函数是个纯虚函数!
接下来该怎么办呢?既然功能顺利执行了,那么这个纯虚函数一定会有一个实现的。这个实现类必然是window类的子类。
所以我们在OnCreate里面加上一行代码 Window w = this.getWindow();
然后通过Eclipse的调试器,利用RTTI查看其实现类,结果如下图:
可以看的很清楚,实现类是 PhoneWindow ,
这样我们就可以到 PhoneWindow 的源码中去查找performPanelShortcut的实现了。
在PhoneWindow.java中我们可以看到如下代码片段:
- // Only try to perform menu shortcuts if preparePanel returned true (possible false
- // return value from application not wanting to show the menu).
- if ((st.isPrepared || preparePanel(st, event)) && st.menu != null) {
- // The menu is prepared now, perform the shortcut on it
- handled = st.menu.performShortcut(keyCode, event, flags);
- }
终于看到menu字样了,这里我们可以看到 if 里面描述的调用条件,
首先当前panel必须已经准备好了(你可以用 onPreparePanel 截获到准备请求),
其次,当前panel必须是有Menu的!(st.menu != null),
从这里我们可以明白DEFAULT_KEYS_SHORTCUT对于没有menu的应用是没有任何效果的。
而且在另一处代码我们会看到还要进行 isShortCut 的判断,所以对于没有快捷键的菜单也是没有任何效果的。
那么我们再看看 preparePanel 里面是如何实现的,在其实现中可以找到如下代码片段:
- // Callback and return if the callback does not want to show the menu
- if (!cb.onPreparePanel(st.featureId, st.createdPanelView, st.menu)) {
- return false;
- }
至此,就完全明白了!代码在这里回调了 onPreparePanel ,而 onPreparePanel 中会回调 onPrepareOptionsMenu ,
而onPrepareOptionsMenu ,就是我们自己写实现自定义菜单的地方了。
为了验证上述推导,我们在onPrepareOptionsMenu 中放入断点,然后在菜单关闭的情况下,输入快捷键,
运行到断点后查看调用堆栈,入下图所示:
堆栈调用顺序可以很清楚的看出我们的推导过程是正确的。至此 DEFAULT_KEYS_SHORTCUT 的实现分析完毕。
总结:
我之所以非常喜爱和看好android平台,就是因为她是开源的,
当我们对任何一个问题有疑问时,都可以把她扒光了细看,呵呵。
而apple的IOS,尽管你很美,但是你的内心实在太难捉摸了。
从本文的分析过程可以看出,平台任何一个看似神奇的功能的实现,
背后都有安卓源码开发者们大巧不工重剑无锋的的实现。
本文对DEFAULT_KEYS_SHORTCUT的分析实际上是很浅显的,
如果细看源码,会发现更多的有意思的地方的。
学习安卓,
也许源码就是最好的老师。^_^
发表评论
-
【Android】监听SDCard安装和卸载的代码片段(测试通过)
2012-03-21 18:39 2234// 监听类 private final Bro ... -
【Android】实现XML解析的几种技术
2012-03-16 16:52 3403本文介绍在Android平台中实现对XML的三种 ... -
【Android】AlarmManager简介
2012-03-15 20:15 2039AlarmManager 包含的主要方法: ... -
【Android】AlarmManager深入学习
2012-03-15 20:13 2049对应AlarmManage有一个AlarmManager ... -
【Android】this和this.getApplictionContext的区别 (转载)
2012-03-08 15:30 2863在android中常常会遇到与context有关的内容, ... -
【Android】在QQ通讯录,360之前拦截短信(intent-filter的优先级)
2012-06-26 11:28 3420原文:http://www.bangchui.org/sim ... -
【Android】xml文件里面出现unbound prefix的问题
2012-02-06 15:25 39356相信有很多菜鸟在编写xml文件的时候,都会遇 ... -
【Android】模拟器启动不了 emulator: ERROR: unknown virtual device name
2012-02-06 15:24 3082很多人在配置android环境的时候卡了壳,一切准备工作 ... -
【Android】Intent 和 Intent Filter 官方文档读后总结
2012-02-03 17:46 2299Intent 和 Intent Filter 1 ... -
【Android】Intent 和 Intent Filter
2012-02-03 17:42 1507转自:http://www.cnblogs.com/Andro ... -
【Android】Android 手机杀进程并不省电,效果只能适得其反
2011-11-29 11:21 4947大家可能是被windows毒 ... -
【Android】BroadcastReceiver简介和用法实例,两种注册方式 (二)
2011-11-24 10:52 10026一.BroadcastReceiver简介 B ... -
【Android】BroadCastReceiver 简介
2011-11-24 10:50 3779BroadCastReceiver 简介 Bro ... -
【Android】四大组件之Service(服务)
2011-11-24 10:49 2270Service是Andorid系统提供的四大组件之一,它 ... -
【Android】BroadcastReceiver发送intent给service或者activity
2011-11-24 10:46 7006BroadcastReceiver:对象的生命周期不超过5s, ... -
【Android】理解Service和BroadcastReceiver(转载)
2011-11-24 10:45 2448Service与Activity类似,也需要在Manifest ... -
【Android】监听文件和目录的创建删除移动等事件
2011-11-16 10:36 2773出于安全上的需要,我们经常需要监听sd卡或者其他路径上的 ... -
【Android】如何在Activity中启动另一应用程序的方法,无需得到类名
2011-11-16 10:33 3141在网上搜索了一会相关的实现代码,发现所有的文章都说是需要 ... -
【Android】loadData与loadDataWithBaseURL的区别
2011-11-10 13:54 34198在写WebView时,感觉LoadUrl太浪费流量,而且 ... -
【Android】检测手机摇晃
2011-11-10 11:10 4465做游戏的时候,一般都要使用到多种多样的传感器,以实现比较丰 ...
相关推荐
现在只需要在桌面上拖动添加,然后运行该程序,就会生成当前桌面应用和窗口小部件的布局文件,保存在/mnt/sdcard/default_workspace.xml中。 将该文件直接替换packages\apps\Launcher2\res\xml-sw720dp\default_...
android:resource="@string/shortcut_title" /> android:name="android.shortcut.icon" android:resource="@drawable/shortcut_icon" /> ``` 这里,我们为`ShortcutActivity`添加了必要的元数据,包括快捷方式...
下面根据提供的文件内容,介绍一些常见的SAP快捷键及其功能描述。 **标准工具栏按钮快捷键**: - **Enter键**:执行“Enter/Continue”功能。 - **Ctrl + S**:保存当前操作。 - **F3键**:返回上一个屏幕。 - **...
Android的Launcher程序是Android操作系统的核心组件之一,它作为用户的主屏幕,承载着应用程序快捷方式、小部件、文件夹等元素,直接影响着用户的交互体验。在深入理解Android Launcher之前,我们首先要明白Launcher...
在`ShortCut.c`中,我们可以预期找到实现快捷方式创建功能的主要逻辑。这个源文件可能包含了读取命令行参数、解析目标路径、创建快捷方式对象以及设置快捷方式属性等函数。源代码的分析和学习可以帮助我们理解如何...
C#编程 WinForm窗体开发 ShortCutMenu(源码)C#编程 WinForm窗体开发 ShortCutMenu(源码)C#编程 WinForm窗体开发 ShortCutMenu(源码)C#编程 WinForm窗体开发 ShortCutMenu(源码)C#编程 WinForm窗体开发 ShortCutMenu...
标题"禁用Ctrl+Alt+Del源码 .rar_ctrl alt del_shortcut_system"指向的压缩包文件包含了一种实现这一功能的源代码。 首先,我们需要了解在Windows系统中如何处理键盘事件。Windows操作系统有一个称为WinAPI...
总之,Android Intent是实现组件间通信的核心工具,它通过Action、Category、Data等属性定义操作,结合BroadcastReceiver和Service,构建了丰富的交互模型,极大地提高了Android应用的灵活性和可扩展性。理解和熟练...
【标题】"qsdk-qca-shortcut-fe-2.7.029.zip" 是一个包含QCA SDK(Qualcomm Atheros Software Development Kit)的压缩...使用这个SDK,开发者可以深入理解芯片的工作原理,优化无线连接,以及实现定制化的网络功能。
`EXTRA_SHORTCUT_NAME`用于设定快捷方式的名称,`EXTRA_SHORTCUT_INTENT`则定义了点击快捷方式时启动的Activity,`EXTRA_SHORTCUT_ICON_RESOURCE`用于设置快捷方式的图标。 删除快捷方式的代码如下: ```java ...
本资源“Android高级应用源码-创建桌面快捷方式源代码.zip”提供了一个实例,帮助开发者理解如何在Android系统中实现这一功能。 首先,我们需要了解Android中的Intent对象,它是Android系统用来传递消息和启动服务...
+ <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.VOICE_LAUNCH" /> + <category android:name="com.android.settings.SHORTCUT" /> + + <...
在Android系统中,快捷方式(Shortcut)是一种方便用户快速访问应用程序特定功能或活动的方式。创建快捷方式可以让用户在主屏幕上直接启动某个应用的功能,而无需打开应用本身。本教程将详细讲解如何在Android中创建和...
ShortCut.exe_命令行创建快捷方式。 例: shortcut /? shortcut D:\Tencent\QQ\Bin\QQ.exe /h ctrl+shift+alt+f4 /ld c.lnk shortcut D:\Tencent\QQ\Bin\QQ.exe /d hello /ld c.lnk shortcut D:\Tencent\QQ\Bin\...
Altium Designer 快捷键整理,包括原理图及原理图库编辑,PCB及元器件封装库编辑,解放右手,轻松画图,事半功倍。
ShortcutInfo shortcut = new ShortcutInfo.Builder(context, "shortcut_id") .setShortLabel("快捷方式") .setLongLabel("这是我的快捷方式") .setIcon(Icon.createWithResource(context, R.drawable.ic_...
这个“Android高级应用源码-快捷图标的创建与移除”压缩包包含了一个示例项目,用于演示如何在Android系统中动态地添加和删除快捷图标。以下是对这个主题的详细讨论: 首先,我们来了解如何创建快捷图标。在Android...
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.VOICE_LAUNCH" /> <category android:name=...
"Shortcut_fix.exe"很显然是Shortcutfix软件的可执行文件,用户通过运行这个文件来启动和使用软件。".exe"扩展名表示这是一个Windows可执行程序。而“绿盟.url”则是一个网址快捷方式,可能指向该软件的官方网站或者...