在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. <?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. <?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. 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. 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. Intentintent= 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 OnTouchListenerhomeOnTouch= new OnTouchListener(){ 13. //@Override 14. public boolean onTouch(Viewv,MotionEventevent) 15. { 16. //TODOAuto-generatedmethodstub 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 OnTouchListenerbackOnTouch= new OnTouchListener(){ 29. //@Override 30. public boolean onTouch(Viewv,MotionEventevent) 31. { 32. //TODOAuto-generatedmethodstub 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 OnTouchListenermenuOnTouch= new OnTouchListener(){ 45. //@Override 46. public boolean onTouch(Viewv,MotionEventevent) 47. { 48. //TODOAuto-generatedmethodstub 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(MotionEventevent){ 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. //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. 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, "ReceivedACTION_ICONKEY_CHANGED" ); 3. updateIconKeyAction(intent); 4. }


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

1. private final void updateIconKeyAction(Intentintent){ 2. int keycode=intent.getIntExtra( "keycode" ,- 1 ); 3. IWindowManagerwm=IWindowManager.Stub.asInterface(ServiceManager.getService( "window" )); 4. 5. if (keycode!=- 1 ){ 6. long now=SystemClock.uptimeMillis(); 7. 8. KeyEventdown= new KeyEvent(now,now,KeyEvent.ACTION_DOWN,keycode, 0 ); 9. KeyEventup= new KeyEvent(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. 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开发板上的效果如下图

更多相关文章

  1. android EditText实例 删除按钮 与内容监听
  2. Android Apk反编译函数对应法则
  3. Android 4.x上适配设置DialogFragment背景透明--可拓展实现悬浮
  4. Android自定义添加圆角渐变色按钮+点击效果
  5. Android 的一些实用的函数
  6. android 按钮效果的两种实现方法
  7. 判断移动端是否是返回按钮,并刷新
  8. android binder机制及其源码解析之第二节 重要函数讲解之常用数
  9. Android : 巧用RadioGroup作为Tab切换的按钮

随机推荐

  1. android 系统权限大全的简介与内容
  2. Android(安卓)电影简介分析源码
  3. Android官方开发文档Training系列课程中
  4. Ionic3学习笔记(九)关于 Android(安卓)端软
  5. android 自动化测试的傻瓜实践之旅(UI篇)
  6. 尝试android(一)--安装配置
  7. 转载:Android获取其他包的Context和在任意
  8. Android要走的路还很长(ZZ)
  9. 《Android深入透析》之广播(Broadcast)
  10. Android(安卓)Market新反盗版机制原理