Android 2.3狀態欄中添加menu home back快捷鍵

在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/目錄下
同時,在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.       <?xmlversion="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 underthe Apache License, Version 2.0 (the "License");

8.       ** you may not usethis file except in compliance with the License.

9.       ** You may obtain acopy of the License at

10.     **

11.     **    http://www.apache.org/licenses/LICENSE-2.0

12.     **

13.     ** Unless requiredby applicable law or agreed to in writing, software

14.     ** distributedunder the License is distributed on an "AS IS" BASIS,

15.     ** WITHOUTWARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

16.     ** See the Licensefor the specific language governing permissions and

17.     ** limitationsunder 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.         <LinearLayoutandroid:id="@+id/icons"

31.             android:layout_width="match_parent"

32.             android:layout_height="match_parent"

33.             android:orientation="horizontal">             

34.             <com.android.systemui.statusbar.IconMergerandroid: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.             <LinearLayoutandroid: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.     <ImageButtonandroid: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.       <ImageButtonandroid: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.       <ImageButtonandroid: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.         <LinearLayoutandroid: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.             <ImageSwitcherandroid: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.TickerViewandroid: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.DateViewandroid: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.       publicStatusBarView(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.         publicstatic 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 = 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;

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.       voidperformExpand() { 

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.        voidperformCollapse() {

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卡對應的目錄即可,   最後的效果如下圖
 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章