咖啡伴侶

          呆在上海
          posts - 163, comments - 156, trackbacks - 0, articles - 2

          在Android 2.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/目錄下
          同時,在frameworks/base/packages/SystemUI/res/drawable 下創建三個imageButton的xml文件
          xml_stat_home.xml

          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.   </selector> 



           xml_stat_back.xml

          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

          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.   </selector>   

          修改status_bar.xml成如下
          目錄:frameworks/base/packages/SystemUI/res/layout/status_bar.xml

          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.      
          21.     <!--    android:background="@drawable/status_bar_closed_default_background" -->
          22.     <com.android.systemui.statusbar.StatusBarView
          23.         xmlns:android="http://schemas.android.com/apk/res/android"
          24.         android:background="@drawable/statusbar_background"
          25.         android:orientation="vertical"
          26.         android:focusable="true"
          27.         android:descendantFocusability="afterDescendants"
          28.         >
          29.      
          30.         <LinearLayout android:id="@+id/icons"
          31.             android:layout_width="match_parent"
          32.             android:layout_height="match_parent"
          33.             android:orientation="horizontal">              
          34.             <com.android.systemui.statusbar.IconMerger android:id="@+id/notificationIcons"
          35.                 android:layout_width="0dip"
          36.                 android:layout_weight="1"
          37.                 android:layout_height="match_parent"
          38.                 android:layout_alignParentLeft="true"
          39.                 android:paddingLeft="6dip"
          40.                 android:gravity="center_vertical"
          41.                 android:orientation="horizontal"/> 
          42.                 
          43.             <LinearLayout android:id="@+id/statusIcons"
          44.                 android:layout_width="wrap_content"
          45.                 android:layout_height="match_parent"
          46.                 android:layout_alignParentRight="true"
          47.                 android:paddingRight="6dip"
          48.                 android:gravity="center_vertical"
          49.                 android:orientation="horizontal"/>   
          50.     <ImageButton android:id="@+id/go_home" 
          51.            android:layout_width="32px" 
          52.            android:layout_height="32px" 
          53.            android:layout_alignParentLeft="true"
          54.                     android:paddingLeft="10dip"
          55.            android:paddingTop="10dip"
          56.                     android:gravity="center_vertical"
          57.            android:clickable="true"  
          58.            android:background="@drawable/xml_stat_home" 
          59.            />  
          60.       <ImageButton android:id="@+id/pop_menu" 
          61.            android:layout_width="32px" 
          62.            android:layout_height="32px" 
          63.            android:layout_alignParentRight="true"
          64.             android:paddingLeft="10dip"
          65.            android:paddingTop="10dip"
          66.             android:gravity="center_vertical"
          67.             android:orientation="horizontal" 
          68.            android:clickable="true"  
          69.            android:background="@drawable/xml_stat_menu" 
          70.            />         
          71.       <ImageButton android:id="@+id/go_back" 
          72.            android:layout_width="32px" 
          73.            android:layout_height="32px" 
          74.            android:layout_alignParentRight="true"
          75.             android:paddingLeft="10dip"
          76.            android:paddingTop="10dip"
          77.             android:gravity="center_vertical"
          78.             android:orientation="horizontal" 
          79.            android:clickable="true"  
          80.            android:background="@drawable/xml_stat_back" 
          81.            />                  
          82.             <com.android.systemui.statusbar.Clock
          83.                 android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"
          84.                 android:layout_width="wrap_content"
          85.                 android:layout_height="match_parent"
          86.                 android:singleLine="true"
          87.                 android:paddingRight="6dip"
          88.                 android:gravity="center_vertical|left"
          89.                 />
          90.         </LinearLayout>
          91.             
          92.         <LinearLayout android:id="@+id/ticker"
          93.             android:layout_width="match_parent"
          94.             android:layout_height="match_parent"
          95.             android:paddingLeft="6dip"
          96.             android:animationCache="false"
          97.             android:orientation="horizontal" >
          98.             <ImageSwitcher android:id="@+id/tickerIcon"
          99.                 android:layout_width="wrap_content"
          100.             android:layout_height="match_parent"
          101.             android:layout_marginRight="8dip"
          102.             >
          103.             <com.android.systemui.statusbar.AnimatedImageView
          104.                 android:layout_width="25dip"
          105.                 android:layout_height="25dip"
          106.                 />
          107.             <com.android.systemui.statusbar.AnimatedImageView
          108.                 android:layout_width="25dip"
          109.                 android:layout_height="25dip"
          110.                 />
          111.         </ImageSwitcher>
          112.         <com.android.systemui.statusbar.TickerView android:id="@+id/tickerText"
          113.             android:layout_width="0dip"
          114.             android:layout_weight="1"
          115.             android:layout_height="wrap_content"
          116.             android:paddingTop="2dip"
          117.             android:paddingRight="10dip">
          118.             <TextView
          119.                 android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
          120.                 android:layout_width="match_parent"
          121.                 android:layout_height="wrap_content"
          122.                 android:singleLine="true"
          123.                 />
          124.             <TextView
          125.                 android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
          126.                 android:layout_width="match_parent"
          127.                 android:layout_height="wrap_content"
          128.                 android:singleLine="true"
          129.                 />
          130.         </com.android.systemui.statusbar.TickerView>
          131.     </LinearLayout>
          132.  
          133.     <com.android.systemui.statusbar.DateView android:id="@+id/date"
          134.         android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"
          135.         android:layout_width="wrap_content"
          136.         android:layout_height="match_parent"
          137.         android:singleLine="true"
          138.         android:gravity="center_vertical|left"
          139.         android:paddingLeft="6px"
          140.         android:paddingRight="6px"
          141.         android:background="@drawable/statusbar_background"
          142.         />
          143. </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;)
           public static final int RESV_KEY_HOME = KeyEvent.KEYCODE_HOME;
           public static final int RESV_KEY_BACK = KeyEvent.KEYCODE_BACK;
           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.         voidsendIntent(Intentintent
          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.       
          12.     private OnTouchListener homeOnTouch = new OnTouchListener(){  
          13.         //@Override     
          14.            public boolean onTouch(View v, MotionEvent event)   
          15.            {     
          16.                // TODO Auto-generated method stub       
          17.                switch (event.getAction()) {  
          18.                    case MotionEvent.ACTION_UP:  
          19.                    {  
          20.                     sendKeyIntent(RESV_KEY_HOME);             
          21.                 }  
          22.                    break;  
          23.                }  
          24.                return false;     
          25.            }   
          26.     };  
          27.       
          28.     private OnTouchListener backOnTouch = new OnTouchListener(){  
          29.         //@Override     
          30.            public boolean onTouch(View v, MotionEvent event)   
          31.            {     
          32.                // TODO Auto-generated method stub       
          33.                switch (event.getAction()) {  
          34.                    case MotionEvent.ACTION_UP:  
          35.                    {  
          36.                     sendKeyIntent(RESV_KEY_BACK);      
          37.                    }  
          38.                    break;  
          39.                }  
          40.                return false;     
          41.            }   
          42.     };  
          43.       
          44.     private OnTouchListener menuOnTouch = new OnTouchListener(){  
          45.         //@Override     
          46.            public boolean onTouch(View v, MotionEvent event)   
          47.            {     
          48.                // TODO Auto-generated method stub       
          49.                switch (event.getAction()) {  
          50.                    case MotionEvent.ACTION_UP:  
          51.                    {  
          52.                     sendKeyIntent(RESV_KEY_MENU);    
          53.                    }  
          54.                    break;  
          55.                }  
          56.                return false;     
          57.            }   
          58.     }; 


          為防止點擊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";
          5.            


          接收并處理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 = new BroadcastReceiver() 加入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;

          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.         
          7.       public void showHotIcons(){  
          8.           mHomeBtn.setVisibility(View.VISIBLE);  
          9.           mBackBtn.setVisibility(View.VISIBLE);  
          10.         mMenuBtn.setVisibility(View.VISIBLE);  
          11.     }


          拉出或收回通知欄中,就可以調用這個函數來顯示或隱藏這幾個按鈕。
          修改文件: statusBarService.java
          目錄:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java

          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.        mExpanded = true;
          10.      makeExpandedVisible();
          11.      mStatusBarView.hiddenHotIcons();
          12.     updateExpandedViewPos(EXPANDED_FULL_OPEN);
          13.     if (false) postStartTracing();
          14.     }
          15.        void performCollapse() {
          16.             if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded
          17.                     + " mExpandedVisible=" + mExpandedVisible
          18.                     + " mTicking=" + mTicking);
          19.      
          20.             if (!mExpandedVisible) {
          21.                 return;
          22.             }
          23.             mExpandedVisible = false;
          24.             visibilityChanged(false);
          25.             mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
          26.             mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
          27.             mExpandedDialog.getWindow().setAttributes(mExpandedParams);
          28.             mTrackingView.setVisibility(View.GONE);
          29.             mExpandedView.setVisibility(View.GONE);
          30.      
          31.             mStatusBarView.showHotIcons();
          32.      
          33.             if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
          34.                 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
          35.             }
          36.             if (mDateView.getVisibility() == View.VISIBLE) {
          37.                 setDateViewVisibility(false, com.android.internal.R.anim.fade_out);
          38.             }
          39.      
          40.             if (!mExpanded) {
          41.                 return;
          42.             }
          43.             mExpanded = false;
          44.         }

          編譯工程 
          #source  /opt/android_froyo_smdk/build/envsetup.sh
          #export   TARGET_PRODUCT=full_smdkv210
          #mmm frameworks/base/
          把編譯生成的相關文件放進SD卡對應的目錄即可,   在偉研科技 WY-S5PV210開發板上的效果如下圖

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 西平县| 黎平县| 大石桥市| 沙田区| 鄂温| 永康市| 永兴县| 新宾| 巴青县| 天柱县| 淅川县| 堆龙德庆县| 新泰市| 乐陵市| 江西省| 洛阳市| 明星| 平山县| 麻城市| 清原| 衡山县| 固镇县| 屏南县| 白银市| 湘乡市| 泊头市| 牡丹江市| 响水县| 台山市| 鹿泉市| 沈阳市| 南城县| 黄平县| 奉化市| 绥宁县| 弋阳县| 南京市| 乌兰察布市| 云南省| 万源市| 合江县|