• 菜单实现Android中的常量 DEFAULT_KEYS_SHORTCUT


    文章结束给大家来个程序员笑话:[M]

        

    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

        

     

        

    [java] view plaincopy
     
    1. package com.silenceburn;  
    2.   
    3. import android.app.Activity;  
    4. import android.os.Bundle;  
    5.   
    6. public class MenuShortCutTester extends Activity {  
    7.     /** Called when the activity is first created. */  
    8.     @Override  
    9.     public void onCreate(Bundle savedInstanceState) {  
    10.         super.onCreate(savedInstanceState);  
    11.         setContentView(R.layout.main);  
    12.           
    13.         setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);  
    14.     }  
    15. }  

         

        

     

        

     

        

    为默许的main.xml中的TextView加增一个id属性,之后我们会用菜单选项控制这行字的颜色

        

     

        

    [xhtml] view plaincopy
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:orientation="vertical"  
    4.     android:layout_width="fill_parent"  
    5.     android:layout_height="fill_parent"  
    6.     >  
    7. <TextView   
    8.     android:id="@+id/myText"   
    9.     android:layout_width="fill_parent"   
    10.     android:layout_height="wrap_content"   
    11.     android:text="@string/hello"  
    12.     />  
    13. </LinearLayout>  

         

        

     

        

     

        

    用使findViewById取获上一步中义定了id的本文对象,将其用引保存在成员变量b中。

        

    写重onPrepareOptionsMenu方法,加增我们自己的菜单项,并册注快捷键,同时加增菜单点击的响应事件。

        

     

        

    [java] view plaincopy
     
    1. package com.silenceburn;  
    2.   
    3. import android.app.Activity;  
    4. import android.os.Bundle;  
    5. import android.view.Menu;  
    6. import android.view.MenuItem;  
    7. import android.view.MenuItem.OnMenuItemClickListener;  
    8. import android.widget.TextView;  
    9.   
    10. public class MenuShortCutTester extends Activity {  
    11.     /** Called when the activity is first created. */  
    12.     TextView b;  
    13.       
    14.     @Override  
    15.     public void onCreate(Bundle savedInstanceState) {  
    16.         super.onCreate(savedInstanceState);  
    17.         setContentView(R.layout.main);  
    18.           
    19.         b = (TextView) this.findViewById(R.id.myText);  
    20.           
    21.         setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);  
    22.     }  
    23.       
    24.     @Override  
    25.     public boolean onPrepareOptionsMenu(Menu menu) {  
    26.         // TODO Auto-generated method stub  
    27.         super.onPrepareOptionsMenu(menu);  
    28.           
    29.         menu.removeItem(0);  
    30.         menu.removeItem(1);  
    31.         menu.add( 000"One").setShortcut('0''0').setOnMenuItemClickListener(new OnMenuItemClickListener(){  
    32.   
    33.             @Override  
    34.             public boolean onMenuItemClick(MenuItem item) {  
    35.                 // TODO Auto-generated method stub  
    36.                 b.setBackgroundColor(android.graphics.Color.RED);  
    37.                 return true;  
    38.             }});  
    39.         menu.add( 010"Two").setShortcut('1''1').setOnMenuItemClickListener(new OnMenuItemClickListener(){  
    40.   
    41.             @Override  
    42.             public boolean onMenuItemClick(MenuItem item) {  
    43.                 // TODO Auto-generated method stub  
    44.                 b.setBackgroundColor(android.graphics.Color.GREEN);  
    45.                 return true;  
    46.             }});   
    47.           
    48.         return true;  
    49.     }  
    50. }  
        每日一道理
    青春,有嬉笑声与哭泣声夹杂的年华,青春的少年是蓝天中翱翔的幼鹰,虽然没有完整长大,有些稚气,有些懵懂,脱不开父母的双手却极力想去找寻属于自己的一片天空,为的是一时的激情,为的是一种独自翱翔的感觉!

         

        

     

        

     

        

    意注我们一共册注了两个菜单项,

        

    一个叫“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中可以找到如下码代片段:

        

     

        

     

        

    [java] view plaincopy
     
    1. if (mDefaultKeyMode == DEFAULT_KEYS_DISABLE) {  
    2.     return false;  
    3. else if (mDefaultKeyMode == DEFAULT_KEYS_SHORTCUT) {  
    4.     if (getWindow().performPanelShortcut(Window.FEATURE_OPTIONS_PANEL,   
    5.             keyCode, event, Menu.FLAG_ALWAYS_PERFORM_CLOSE)) {  
    6.         return true;  
    7.     }  
    8.     return false;  
    9. }  

         

        

     

        

    由此可知,当统系检测到 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中我们可以看到如下码代片段:

        

     

        

    [java] view plaincopy
     
    1. // Only try to perform menu shortcuts if preparePanel returned true (possible false  
    2. // return value from application not wanting to show the menu).  
    3. if ((st.isPrepared || preparePanel(st, event)) && st.menu != null) {  
    4.     // The menu is prepared now, perform the shortcut on it  
    5.     handled = st.menu.performShortcut(keyCode, event, flags);  
    6. }  

         

        

     

        

    于终看到menu字样了,这里我们可以看到 if 里头述描的调用条件,

        

    首先以后panel必须已预备好了(你可以用 onPreparePanel 截获到预备求请),

        

    其次,以后panel必须是有Menu的!(st.menu != null),

        

    从这里我们可以白明DEFAULT_KEYS_SHORTCUT对于没有menu的应用是没有任何效果的。

        

    而且在另外一处码代我们会看到还要停止 isShortCut 的判断,所以对于没有快捷键的菜单也是没有任何效果的。

        

     

        

    那么我们再看看 preparePanel 里头是如何实现的,在其实现中可以找到如下码代片段:

        

     

        

    [java] view plaincopy
     
    1. // Callback and return if the callback does not want to show the menu  
    2. if (!cb.onPreparePanel(st.featureId, st.createdPanelView, st.menu)) {  
    3.     return false;  
    4. }  

         

        

     

        

    至此,就完整白明了!码代在这里回调了 onPreparePanel ,而 onPreparePanel  中会回调  onPrepareOptionsMenu ,

        

    而onPrepareOptionsMenu ,就是我们自己写实现自义定菜单的地方了。

        

     

        

    为了验证上述推导,我们在onPrepareOptionsMenu 中放入断点,然后在菜单闭关的情况下,输入快捷键,

        

    运行到断点后查看调用堆栈,入下图所示:

        

     

        

     菜单和实现

        

     

        

    堆栈调用次序可以很楚清的看出我们的推导进程是准确的。至此 DEFAULT_KEYS_SHORTCUT 的实现析分毕完。

        

     

        


    文章结束给大家分享下程序员的一些笑话语录: 神灯新篇
    一个程序员在海滩上发现了一盏神灯。他在灯上擦了几下,一个妖怪就从灯里跳出来说:“我是世界上法术最强的妖怪。我可以实现你的任何梦想,但现在,我只能满足你一个愿望。”程序员摊开了一幅中东地图说:“我想让中东得到永久的和平。”妖怪答道:“哦,我没办法。自打创世纪以来,那里的战火就没有停息过。这世上几乎没有我办不到的事,但这件事除外。”程序员于是说:“好吧,我是一个程序员,为许多用户编写过程序。你能让他们把需求表述得更清楚些,并且让我们的软件项目有那么一两次按进度按成本完成吗?”妖怪说:“唔,我们还是来看中东地图吧。”

  • 相关阅读:
    web安全之sql注入实例(5.0之前的)
    http和htpps
    web安全之sql注入原理
    web安全之http协议
    题解洛谷P1538【迎春舞会之数字舞蹈】
    [模板]洛谷T3375 KMP字符串匹配
    [模板]洛谷T2158 仪仗队 欧拉函数
    洛谷T1967 货车运输 Kruskal最大生成树&&倍增LCA
    [模板]洛谷T3380 二逼平衡树 线段树套BST
    [模板]洛谷T3384 树链剖分
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3069889.html
Copyright © 2020-2023  润新知