android 源码 在状态栏添加 虚拟按键(back,home,menu)

的版本有用,android2.3的代码和架构发生了不少变化,下面说说如何在在android2.3实现在状态栏中增加menu,home和back快捷键,本文大部分引用上面两篇文章,感谢两篇博文作者提供参考。

 

 1、准备资源,修改XML文

准备几张图,这里我们准备添加home back和menu图标,就需要准备6张图,三张普通状态,三张按下的高亮状态图标:

stat_home.png

stat_home_pressed.png

stat_back.png

stat_back_pressed.png

stat_menu.png

stat_menu_pressed.png

把它们放在frameworks/base/packages/SystemUI/res/drawable/目录下

同时,[B]在[/B]frameworks/base/packages/SystemUI/res/drawable下创建三个imageButton的xml文件

xml_stat_home.xml

 

 

[xhtml] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>                                          
  2. <selector                                                                             
  3.     xmlns:android="http://schemas.android.com/apk/res/android">                       
  4.     <item                                                                             
  5.         android:state_focused="true"                                                  
  6.         android:state_pressed="false"                                                 
  7.         android:drawable="@drawable/stat_home" />                                     
  8.     <item                                                                             
  9.         android:state_focused="true"                                                  
  10.       android:state_pressed="true"                                                    
  11.       android:drawable="@drawable/stat_home_pressed" />                               
  12.   <item                                                                               
  13.       android:state_focused="false"                                                   
  14.       android:state_pressed="true"                                                    
  15.       android:drawable="@drawable/stat_home_pressed" />                               
  16.   <item                                                                               
  17.       android:drawable="@drawable/stat_home" />                                       
  18. t;/selector>  
  

 

xml_stat_back.xml                                                                       

    

[xhtml] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>                                               
  2.     <selector                                                                            
  3.         xmlns:android="http://schemas.android.com/apk/res/android">                      
  4.         <item                                                                            
  5.             android:state_focused="true"                                                 
  6.             android:state_pressed="false"                                                
  7.             android:drawable="@drawable/stat_back" />                                    
  8.         <item                                                                            
  9.             android:state_focused="true"                                                 
  10.           android:state_pressed="true"                                                   
  11.           android:drawable="@drawable/stat_back_pressed" />                              
  12.       <item                                                                              
  13.           android:state_focused="false"                                                  
  14.           android:state_pressed="true"                                                   
  15.           android:drawable="@drawable/stat_back_pressed" />                              
  16.       <item                                                                              
  17.           android:drawable="@drawable/stat_back" />                                      
  18.   </selector>        
 

 

xml_stat_menu.xml                                                                       

 

[xhtml] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>                                               
  2. <selector                                                                            
  3.     xmlns:android="http://schemas.android.com/apk/res/android">                      
  4.     <item                                                                            
  5.         android:state_focused="true"                                                 
  6.         android:state_pressed="false"                                                
  7.         android:drawable="@drawable/stat_menu" />                                    
  8.     <item                                                                            
  9.         android:state_focused="true"                                                 
  10.       android:state_pressed="true"                                                   
  11.       android:drawable="@drawable/stat_menu_pressed" />                              
  12.   <item                                                                              
  13.       android:state_focused="false"                                                  
  14.       android:state_pressed="true"                                                   
  15.       android:drawable="@drawable/stat_menu_pressed" />                              
  16.   <item                                                                              
  17.       android:drawable="@drawable/stat_menu" />                                      
  18. t;/selector>        
                                                                    

 

修改status_bar.xml成如下

目录:frameworks/base/packages/SystemUI/res/layout/status_bar.xml

 

 

 

 

 

[xhtml] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.  <!--  
  3.  /* apps/common/assets/default/default/skins/StatusBar.xml  
  4.  **  
  5.  ** Copyright 2006, The Android Open Source Project  
  6.  **  
  7.  ** Licensed under the Apache License, Version 2.0 (the "License");  
  8.  ** you may not use this file except in compliance with the License.  
  9.  ** You may obtain a copy of the License at  
  10. **  
  11. **     http://www.apache.org/licenses/LICENSE-2.0  
  12. **  
  13. ** Unless required by applicable law or agreed to in writing, software  
  14. ** distributed under the License is distributed on an "AS IS" BASIS,  
  15. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  16. ** See the License for the specific language governing permissions and  
  17. ** limitations under the License.  
  18. */  
  19. -->  
  20. <!--    android:background="@drawable/status_bar_closed_default_background" -->  
  21. <com.android.systemui.statusbar.StatusBarView  
  22.     xmlns:android="http://schemas.android.com/apk/res/android"  
  23.     android:background="@drawable/statusbar_background"  
  24.     android:orientation="vertical"  
  25.     android:focusable="true"  
  26.     android:descendantFocusability="afterDescendants"  
  27.     >  
  28.     <LinearLayout android:id="@+id/icons"  
  29.         android:layout_width="match_parent"  
  30.         android:layout_height="match_parent"  
  31.         android:orientation="horizontal">                
  32.         <com.android.systemui.statusbar.IconMerger android:id="@+id/notificationIcons"  
  33.             android:layout_width="0dip"  
  34.             android:layout_weight="1"  
  35.             android:layout_height="match_parent"  
  36.             android:layout_alignParentLeft="true"  
  37.             android:paddingLeft="6dip"  
  38.             android:gravity="center_vertical"  
  39.             android:orientation="horizontal"/>   
  40.         <LinearLayout android:id="@+id/statusIcons"  
  41.             android:layout_width="wrap_content"  
  42.             android:layout_height="match_parent"  
  43.             android:layout_alignParentRight="true"  
  44.             android:paddingRight="6dip"  
  45.             android:gravity="center_vertical"  
  46.             android:orientation="horizontal"/>     
  47. <ImageButton android:id="@+id/go_home"   
  48.        android:layout_width="32px"   
  49.        android:layout_height="32px"   
  50.        android:layout_alignParentLeft="true"  
  51.                 android:paddingLeft="10dip"  
  52.        android:paddingTop="10dip"  
  53.                 android:gravity="center_vertical"  
  54.        android:clickable="true"    
  55.        android:background="@drawable/xml_stat_home"   
  56.        />    
  57.    <ImageButton android:id="@+id/pop_menu"   
  58.        android:layout_width="32px"   
  59.        android:layout_height="32px"   
  60.        android:layout_alignParentRight="true"  
  61.         android:paddingLeft="10dip"  
  62.         android:paddingTop="10dip"  
  63.         android:gravity="center_vertical"  
  64.         android:orientation="horizontal"   
  65.        android:clickable="true"    
  66.        android:background="@drawable/xml_stat_menu"   
  67.        />            
  68.    <ImageButton android:id="@+id/go_back"   
  69.        android:layout_width="32px"   
  70.        android:layout_height="32px"   
  71.         android:layout_alignParentRight="true"  
  72.         android:paddingLeft="10dip"  
  73.        android:paddingTop="10dip"  
  74.         android:gravity="center_vertical"  
  75.         android:orientation="horizontal"   
  76.        android:clickable="true"    
  77.        android:background="@drawable/xml_stat_back"   
  78.        />                    
  79.         <com.android.systemui.statusbar.Clock  
  80.             android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"  
  81.             android:layout_width="wrap_content"  
  82.             android:layout_height="match_parent"  
  83.             android:singleLine="true"  
  84.             android:paddingRight="6dip"  
  85.             android:gravity="center_vertical|left"  
  86.             />  
  87.     </LinearLayout>  
  88.     <LinearLayout android:id="@+id/ticker"  
  89.         android:layout_width="match_parent"  
  90.         android:layout_height="match_parent"  
  91.         android:paddingLeft="6dip"  
  92.         android:animationCache="false"  
  93.         android:orientation="horizontal" >  
  94.         <ImageSwitcher android:id="@+id/tickerIcon"  
  95.             android:layout_width="wrap_content"  
  96.           android:layout_height="match_parent"  
  97.           android:layout_marginRight="8dip"  
  98.           >  
  99.           <com.android.systemui.statusbar.AnimatedImageView  
  100.               android:layout_width="25dip"  
  101.               android:layout_height="25dip"  
  102.               />  
  103.           <com.android.systemui.statusbar.AnimatedImageView  
  104.               android:layout_width="25dip"  
  105.               android:layout_height="25dip"  
  106.               />  
  107.       </ImageSwitcher>  
  108.       <com.android.systemui.statusbar.TickerView android:id="@+id/tickerText"  
  109.           android:layout_width="0dip"  
  110.           android:layout_weight="1"  
  111.           android:layout_height="wrap_content"  
  112.           android:paddingTop="2dip"  
  113.           android:paddingRight="10dip">  
  114.           <TextView  
  115.               android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"  
  116.               android:layout_width="match_parent"  
  117.               android:layout_height="wrap_content"  
  118.               android:singleLine="true"  
  119.               />  
  120.           <TextView  
  121.               android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"  
  122.               android:layout_width="match_parent"  
  123.               android:layout_height="wrap_content"  
  124.               android:singleLine="true"  
  125.               />  
  126.       </com.android.systemui.statusbar.TickerView>  
  127.   </LinearLayout>  
  128.   <com.android.systemui.statusbar.DateView android:id="@+id/date"  
  129.       android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"  
  130.       android:layout_width="wrap_content"  
  131.       android:layout_height="match_parent"  
  132.       android:singleLine="true"  
  133.       android:gravity="center_vertical|left"  
  134.       android:paddingLeft="6px"  
  135.       android:paddingRight="6px"  
  136.       android:background="@drawable/statusbar_background"  
  137.       />  
  138. lt;/com.android.systemui.statusbar.StatusBarView>   
 

 

 

 

二 为按钮添加动态效果

改frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java
在类中新增加四个成员(须导入android.widget.ImageButton和android.content.Context):

 

  1. ImageButton mHomeBtn;        
  2. ImageButton mBackBtn;        
  3. ImageButton mMenuBtn;        
  4. final Context mContext;      
 

 

 

增加三个常量:(须导入android.view.KeyEvent;)

  1. public static final int RESV_KEY_HOME = KeyEvent.KEYCODE_HOME;  
  2. public static final int RESV_KEY_BACK = KeyEvent.KEYCODE_BACK;  
  3. public static final int RESV_KEY_MENU = KeyEvent.KEYCODE_MENU;  
 

 

在构造函数StatusBarView中初始化mContext

 

  1. public StatusBarView(Context context, AttributeSet attrs) {     
  2.          super(context, attrs);  
  3.           mContext=context;  
  4.      }   
 

  注意”mContext=context;”须在”super(context,attrs);”后面,不然编译会报错

在onFinishInflate中,获取几个button 的handler,并设置touch事件,添加如下代码:

 

  1. mHomeBtn = (ImageButton)findViewById(R.id.go_home);    
  2. mBackBtn = (ImageButton)findViewById(R.id.go_back);    
  3. mMenuBtn = (ImageButton)findViewById(R.id.pop_menu);    
  4.          
  5. mHomeBtn.setOnTouchListener(homeOnTouch);    
  6. mBackBtn.setOnTouchListener(backOnTouch);    
  7. mMenuBtn.setOnTouchListener(menuOnTouch);    
 
各button的touch事件添加如下:

 

  1. void sendIntent(Intent intent)   
  2.     {   
  3.         mContext.sendBroadcast(intent);   
  4.     }  
  5. private void sendKeyIntent(int keycode){    
  6.          Intent intent = new    Intent(Intent.ACTION_ICONKEY_CHANGED);    
  7.          intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);    
  8.          intent.putExtra("keycode",   keycode);    
  9.          sendIntent(intent);                
  10.     }    
  11.     private OnTouchListener homeOnTouch = new OnTouchListener(){    
  12.         //@Override       
  13.            public boolean onTouch(View v, MotionEvent event)     
  14.            {       
  15.                // TODO Auto-generated method stub         
  16.                switch (event.getAction()) {    
  17.                    case MotionEvent.ACTION_UP:    
  18.                    {    
  19.                     sendKeyIntent(RESV_KEY_HOME);               
  20.                 }    
  21.                    break;    
  22.                }    
  23.                return false;       
  24.            }     
  25.     };    
  26.     private OnTouchListener backOnTouch = new OnTouchListener(){    
  27.         //@Override       
  28.            public boolean onTouch(View v, MotionEvent event)     
  29.            {       
  30.                // TODO Auto-generated method stub         
  31.                switch (event.getAction()) {    
  32.                    case MotionEvent.ACTION_UP:    
  33.                    {    
  34.                     sendKeyIntent(RESV_KEY_BACK);        
  35.                    }    
  36.                    break;    
  37.                }    
  38.                return false;       
  39.            }     
  40.     };    
  41.     private OnTouchListener menuOnTouch = new OnTouchListener(){    
  42.         //@Override       
  43.            public boolean onTouch(View v, MotionEvent event)     
  44.            {       
  45.                // TODO Auto-generated method stub         
  46.                switch (event.getAction()) {    
  47.                    case MotionEvent.ACTION_UP:    
  48.                    {    
  49.                     sendKeyIntent(RESV_KEY_MENU);      
  50.                    }    
  51.                    break;    
  52.                }    
  53.                return false;       
  54.            }     
  55.     };   
 
为防止点击statusBar上的按钮, 触发标题栏的expend事件, 修改一下函数onInterceptTouchEvent,点击到不属于button区域时才允许解析Motion的event:
  1.      public boolean onInterceptTouchEvent(MotionEvent event) {    
  2.           if(  (event.getX() > mHomeBtn.getRight())        
  3.              &&  (event.getX() < mMenuBtn.getLeft())){          
  4.              return mService.interceptTouchEvent(event)        
  5.                  ? true : super.onInterceptTouchEvent(event);         
  6.              }         
  7.         return false;    
  8.          //return mService.interceptTouchEvent(event)                   
  9.          //  ? true : super.onInterceptTouchEvent(event);    
  10.    }    
  11. }    
 
需要自己添加Intent
打开frameworks/base/core/java/android/content/Intent.java,增加下面的内容,由于我们的使用的API不公开,须加上/**@hide*/,不然编译会报错

  

    

  1. /** 
  2.        * @hide 
  3.        */     
  4.  public static final String ACTION_ICONKEY_CHANGED ="android.intent.action.ICONKEY_CHANGED";  
 

   

  接收并处理intent
修改StatusBarPolicy.java

目录:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java

   首先在构造函数中加入Intent的filter,注册号这个intent的receiver。
filter.addAction(Intent.ACTION_ICONKEY_CHANGED); 
接着在private BroadcastReceiver mIntentReceiver = newBroadcastReceiver() 加入Intent的receiver动作;

 

  1. else if (action.equals(Intent.ACTION_ICONKEY_CHANGED)) {    
  2.                  Log.d(TAG, "Received ACTION_ICONKEY_CHANGED");    
  3.                  updateIconKeyAction(intent);    
  4.              }    
 

及处理函数:
须导入以下包
import android.view.IWindowManager;
import android.os.SystemClock;
import android.view.KeyEvent;
 
 
[java] view plain copy
  1.  private final void updateIconKeyAction(Intent intent){    
  2.      int     keycode = intent.getIntExtra("keycode", -1);    
  3.      IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));    
  4.   
  5.      if(keycode != -1){    
  6.          long now = SystemClock.uptimeMillis();    
  7.   
  8.             KeyEvent down = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keycode, 0);    
  9.             KeyEvent up = new KeyEvent(now, now, KeyEvent.ACTION_UP, keycode, 0);    
  10.   
  11.         try {    
  12.             wm.injectKeyEvent(down, false);    
  13.         }catch (RemoteException e) {    
  14.             Log.i("Input", "DeadOjbectException");    
  15.         }    
  16.   
  17.         try{    
  18.             wm.injectKeyEvent(up, false);    
  19.         }catch(RemoteException e) {    
  20.             Log.i("Input", "DeadOjbectException");    
  21.         }    
  22.     }    
  23. }  
StatusBar通知栏屏蔽按钮
当拉出expand的通知栏时,按钮的响应非常慢,这时最好将按钮给屏蔽掉,我们在 statusBarView.java中增加两个方法:
  1. public void hiddenHotIcons(){    
  2.     mHomeBtn.setVisibility(View.INVISIBLE);    
  3.     mBackBtn.setVisibility(View.INVISIBLE);    
  4.     mMenuBtn.setVisibility(View.INVISIBLE);    
  5. }    
  6. public void showHotIcons(){    
  7.     mHomeBtn.setVisibility(View.VISIBLE);    
  8.     mBackBtn.setVisibility(View.VISIBLE);    
  9.    mMenuBtn.setVisibility(View.VISIBLE);    
 

拉出或收回通知栏中,就可以调用这个函数来显示或隐藏这几个按钮。

修改文件:statusBarService.java

目录:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
 
 
[java] view plain copy
  1.    void performExpand() {  
  2.        if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded);  
  3.        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {  
  4.            return ;  
  5.        }  
  6.        if (mExpanded) {  
  7.            return;  
  8.        }  
  9.       
  10.        mExpanded = true;  
  11.        makeExpandedVisible();  
  12.        mStatusBarView.hiddenHotIcons();  
  13.        updateExpandedViewPos(EXPANDED_FULL_OPEN);  
  14.   
  15.        if (false) postStartTracing();  
  16.    }  
  17.   
  18.    void performCollapse() {  
  19.        if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded  
  20.                + " mExpandedVisible=" + mExpandedVisible  
  21.                + " mTicking=" + mTicking);  
  22.   
  23.        if (!mExpandedVisible) {  
  24.            return;  
  25.        }  
  26.        mExpandedVisible = false;  
  27.        visibilityChanged(false);  
  28.        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  
  29.        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;  
  30.        mExpandedDialog.getWindow().setAttributes(mExpandedParams);  
  31.        mTrackingView.setVisibility(View.GONE);  
  32.        mExpandedView.setVisibility(View.GONE);  
  33.   
  34. mStatusBarView.showHotIcons();  
  35.   
  36.        if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {  
  37.            setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);  
  38.        }  
  39.        if (mDateView.getVisibility() == View.VISIBLE) {  
  40.            setDateViewVisibility(false, com.android.internal.R.anim.fade_out);  
  41.        }  
  42.   
  43.        if (!mExpanded) {  
  44.            return;  
  45.        }  
  46.        mExpanded = false;  
  47.    } 

      最后编译:1. 先更新API,make update-api 

                           2. mmm frameworks/base/packages/SystemUI



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值