现在的位置: 首页 > 综合 > 正文

Android 2.3状态栏中添加menu home back快捷键

2013年09月16日 ⁄ 综合 ⁄ 共 18215字 ⁄ 字号 评论关闭

是转载从网上下载的文章,不知道作者是谁。

 

我在Android 2.3.4  ubuntu系统下用这个方法编译通过,运行正常。

最后加了自已的一点经验,以下是内容:

*********************************

在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卡对应的目录即可,   最后的效果如下图
 

 

 

小结:代码完全没问题,要注意手打别复制粘贴。另外在修改status_bar.xml的时候,把ImageButton的节点插入在如下的位置,可以让按键显示在状态栏的左边。比如home按键:

 

    <LinearLayout android:id="@+id/icons"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
<ImageButton 
    android:id="@+id/go_home"
    android:layout_width="42px"
    android:layout_height="42px"
    android:layout_alignParentLeft="true"
    android:paddingLeft="10dip"
    android:paddingTop="10dip"
    android:gravity="center_vertical"
    android:clickable="true"
    android:background="@drawable/xml_stat_home" />

抱歉!评论已关闭.