`
hyshucom
  • 浏览: 808430 次
文章分类
社区版块
存档分类
最新评论

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. <?xmlversion="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. <?xmlversion="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. <?xmlversion="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. ImageButtonmHomeBtn;

2. ImageButtonmBackBtn;

3. ImageButtonmMenuBtn;

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

6. Intentintent=newIntent(Intent.ACTION_ICONKEY_CHANGED);

7. intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);

8. intent.putExtra("keycode",keycode);

9. sendIntent(intent);

10. }

11.

12. privateOnTouchListenerhomeOnTouch=newOnTouchListener(){

13. //@Override

14. publicbooleanonTouch(Viewv,MotionEventevent)

15. {

16. //TODOAuto-generatedmethodstub

17. switch(event.getAction()){

18. caseMotionEvent.ACTION_UP:

19. {

20. sendKeyIntent(RESV_KEY_HOME);

21. }

22. break;

23. }

24. returnfalse;

25. }

26. };

27.

28. privateOnTouchListenerbackOnTouch=newOnTouchListener(){

29. //@Override

30. publicbooleanonTouch(Viewv,MotionEventevent)

31. {

32. //TODOAuto-generatedmethodstub

33. switch(event.getAction()){

34. caseMotionEvent.ACTION_UP:

35. {

36. sendKeyIntent(RESV_KEY_BACK);

37. }

38. break;

39. }

40. returnfalse;

41. }

42. };

43.

44. privateOnTouchListenermenuOnTouch=newOnTouchListener(){

45. //@Override

46. publicbooleanonTouch(Viewv,MotionEventevent)

47. {

48. //TODOAuto-generatedmethodstub

49. switch(event.getAction()){

50. caseMotionEvent.ACTION_UP:

51. {

52. sendKeyIntent(RESV_KEY_MENU);

53. }

54. break;

55. }

56. returnfalse;

57. }

58. };


为防止点击statusBar上的按钮, 触发标题栏的expend事件, 修改一下函数onInterceptTouchEvent,点击到不属于button区域时才允许解析Motion的event:

1. publicbooleanonInterceptTouchEvent(MotionEventevent){

2. if((event.getX()>mHomeBtn.getRight())

3. &&(event.getX()<mMenuBtn.getLeft())){

4. returnmService.interceptTouchEvent(event)

5. ?true:super.onInterceptTouchEvent(event);

6. }

7. returnfalse;

8. //returnmService.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. elseif(action.equals(Intent.ACTION_ICONKEY_CHANGED)){

2. Log.d(TAG,"ReceivedACTION_ICONKEY_CHANGED");

3. updateIconKeyAction(intent);

4. }


及处理函数:
须导入以下包
import android.view.IWindowManager;
import android.os.SystemClock;
import android.view.KeyEvent;

1. privatefinalvoidupdateIconKeyAction(Intentintent){

2. intkeycode=intent.getIntExtra("keycode",-1);

3. IWindowManagerwm=IWindowManager.Stub.asInterface(ServiceManager.getService("window"));

4.

5. if(keycode!=-1){

6. longnow=SystemClock.uptimeMillis();

7.

8. KeyEventdown=newKeyEvent(now,now,KeyEvent.ACTION_DOWN,keycode,0);

9. KeyEventup=newKeyEvent(now,now,KeyEvent.ACTION_UP,keycode,0);

10.

11. try{

12. wm.injectKeyEvent(down,false);

13. }catch(RemoteExceptione){

14. Log.i("Input","DeadOjbectException");

15. }

16.

17. try{

18. wm.injectKeyEvent(up,false);

19. }catch(RemoteExceptione){

20. Log.i("Input","DeadOjbectException");

21. }

22. }

23. }


StatusBar通知栏屏蔽按钮
当拉出expand的通知栏时,按钮的响应非常慢,这时最好将按钮给屏蔽掉,我们在 statusBarView.java中增加两个方法:

1. publicvoidhiddenHotIcons(){

2. mHomeBtn.setVisibility(View.INVISIBLE);

3. mBackBtn.setVisibility(View.INVISIBLE);

4. mMenuBtn.setVisibility(View.INVISIBLE);

5. }

6.

7. publicvoidshowHotIcons(){

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


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics