由於完全改了status bar,建議先做幾張png圖片,加到
Frameworks/base/core/res/res/drawable
下。最好做一張背景圖,替換 statusbar_background.png
另外我又加了幾張icon,分別是home menu和back的正常和按下狀態。
這些圖片為:
frameworks\base\core\res\res\drawable\ic_menu_back_pressed.png
frameworks\base\core\res\res\drawable\ic_menu_home_pressed.png
frameworks\base\core\res\res\drawable\ic_menu_more_pressed.png
frameworks\base\core\res\res\drawable\ic_volume_down_pressed.png
frameworks\base\core\res\res\drawable\ic_volume_up_pressed.png
frameworks\base\core\res\res\drawable\ic_menu_back.png
frameworks\base\core\res\res\drawable\ic_menu_home.png
frameworks\base\core\res\res\drawable\ic_menu_more.png
frameworks\base\core\res\res\drawable\ic_volume_down.png
frameworks\base\core\res\res\drawable\ic_volume_up.png
修改步驟為:
一.修改xml介面
1.建立按鈕
frameworks\base\core\res\res\drawable\btn_sbicon_back.xml
frameworks\base\core\res\res\drawable\btn_sbicon_home.xml
frameworks\base\core\res\res\drawable\btn_sbicon_menu.xml
frameworks\base\core\res\res\drawable\btn_sbicon_vol_down.xml
frameworks\base\core\res\res\drawable\btn_sbicon_vol_up.xml
基結構如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android ">
<item android:state_pressed="true" android:drawable="@drawable/ic_menu_back_pressed" />
<item android:state_pressed="false" android:drawable="@drawable/ic_menu_back" />
</selector>
2. 增加表徵圖
更改整個status bar,我的方法是:
修改status bar的layerout檔案:
Frameworks/base/core/res/res/layout/status_bar.xml
在原來的linearlayout中新增 image view
<?xml version="1.0" encoding="utf-8"?>
<com.android.server.status.StatusBarView xmlns:android="http://schemas.android.com/apk/res/android "
android:background="@drawable/statusbar_background"
android:orientation="vertical"
android:focusable="true"
android:descendantFocusability="afterDescendants"
>
<LinearLayout android:id="@+id/keys"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView android:id="@+id/status_home"
android:layout_width="40dip"
android:layout_height="40dip"
android:clickable="true"
android:layout_gravity="top"
android:paddingTop="1dip"
android:paddingRight="1dip"
android:paddingLeft="1dip"
android:src="@drawable/btn_sbicon_home" />
<ImageView android:id="@+id/status_back"
android:layout_width="40dip"
android:layout_height="40dip"
android:clickable="true"
android:layout_gravity="top"
android:paddingTop="1dip"
android:paddingRight="1dip"
android:paddingLeft="1dip"
android:src="@drawable/btn_sbicon_back" />
<ImageView android:id="@+id/status_menu"
android:layout_width="40dip"
android:layout_height="40dip"
android:clickable="true"
android:layout_gravity="top"
android:paddingTop="1dip"
android:paddingRight="1dip"
android:paddingLeft="1dip"
android:src="@drawable/btn_sbicon_menu" />
<ImageView android:id="@+id/status_vol_down"
android:layout_width="40dip"
android:layout_height="40dip"
android:clickable="true"
android:layout_gravity="top"
android:paddingTop="1dip"
android:paddingRight="1dip"
android:paddingLeft="1dip"
android:src="@drawable/btn_sbicon_vol_down" />
<ImageView android:id="@+id/status_vol_up"
android:layout_width="40dip"
android:layout_height="40dip"
android:clickable="true"
android:layout_gravity="top"
android:paddingTop="1dip"
android:paddingRight="1dip"
android:paddingLeft="1dip"
android:src="@drawable/btn_sbicon_vol_up" />
</LinearLayout>
......
</com.android.server.status.StatusBarView>
這樣做的好處就是簡單。同時保證home、menu、back按鈕,不受它本來的約束。這樣status bar上即可看到這些按鈕了。
表徵圖的位置,可通過修改 paddingRight, paddingLeft 和paddingTop的值達到最佳視覺效果。
3. 修改status bar的高度。
既然要在status bar上增加那麼幾個按鈕,當然是想要使用觸摸操作的,android內建的status bar高度太小,不適用。對於7寸屏的話,50pixel的高度應該是差不多了。
修改高度很簡單,修改frameworks/base/core/res/res/values/dimens.xml的status_bar_height屬性
<!-- Height of the status bar -->
<dimen name="status_bar_height">50dip</dimen>
也可以更改狀態列Icon的大小,frameworks\base\core\res\res\layout\status_bar_icon.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android "
android:layout_width="25dp"
android:layout_height="25dp" >
當然,如果相改title的高度,可以修改 Frameworks/base/core/res/res/values/themes.xml中的Window attributes的windowTitleSize值
編譯運行一下:
~/donut$ source ./env.sh
~/donut$ make –j8
~/donut$ emulator –skin WVGA800
~/donut$ source ./env.sh
~/donut$ make –j8
~/donut$ emulator –skin WVGA800
看狀態列是不是改變了?
二 為按鈕添加類比按鍵
修改frameworks\base\services\java\com\android\server\status\StatusBarView.java
1.添加各個圖片按鈕的引用,
android.widget.LinearLayout keysLayout;
android.widget.ImageView btnHome;
android.widget.ImageView btnBack;
android.widget.ImageView btnMenu;
android.widget.ImageView btnVolUp;
android.widget.ImageView btnVolDown;
2.修改onFinishInflate()函數,各個圖片ID在上面的status_bar.xml中已經定義
@Override
protected void onFinishInflate() {
......
/* Begin : Added by TigerPan */
keysLayout = (android.widget.LinearLayout)findViewById(R.id.keys);
btnHome = (android.widget.ImageView)findViewById(R.id.status_home);
btnBack = (android.widget.ImageView)findViewById(R.id.status_back);
btnMenu = (android.widget.ImageView)findViewById(R.id.status_menu);
btnVolUp = (android.widget.ImageView)findViewById(R.id.status_vol_up);
btnVolDown = (android.widget.ImageView)findViewById(R.id.status_vol_down);
btnHome.setOnClickListener(mKeysListener);
btnBack.setOnClickListener(mKeysListener);
btnMenu.setOnClickListener(mKeysListener);
btnVolUp.setOnClickListener(mKeysListener);
btnVolDown.setOnClickListener(mKeysListener);
/* End : Added by TigerPan */
}
3.添加各個按鈕的事件監聽Listener
android.view.View.OnClickListener mKeysListener = new android.view.View.OnClickListener(){
public void onClick(View v) {
switch (v.getId()) {
case R.id.status_home:
mKeysHandler.sendEmptyMessage(KEY_HOME);
break;
case R.id.status_back:
mKeysHandler.sendEmptyMessage(KEY_BACK);
break;
case R.id.status_menu:
mKeysHandler.sendEmptyMessage(KEY_MENU);
break;
case R.id.status_vol_up:
mKeysHandler.sendEmptyMessage(KEY_VOL_UP);
break;
case R.id.status_vol_down:
mKeysHandler.sendEmptyMessage(KEY_VOL_DOWN);
break;
default:
break;
}
}};
4.添加類比按鍵處理
/* Begin : ADDED by TigerPan 20100831 */
private static final int KEY_HOME = 1000;
private static final int KEY_BACK = 1001;
private static final int KEY_MENU = 1002;
private static final int KEY_VOL_UP = 1003;
private static final int KEY_VOL_DOWN = 1004;
private Handler mKeysHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case KEY_HOME:
sendKey(KeyEvent.KEYCODE_HOME);
break;
case KEY_BACK:
sendKey(KeyEvent.KEYCODE_BACK);
break;
case KEY_MENU:
sendKey(KeyEvent.KEYCODE_MENU);
break;
case KEY_VOL_UP:
((android.media.AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE))
.adjustVolume(android.media.AudioManager.ADJUST_RAISE, android.media.AudioManager.STREAM_MUSIC);
break;
case KEY_VOL_DOWN:
((android.media.AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE))
.adjustVolume(android.media.AudioManager.ADJUST_LOWER, android.media.AudioManager.STREAM_MUSIC);
break;
default:
break;
}
}
private void sendKey(int keyCode) {
long now = SystemClock.uptimeMillis();
long n = System.currentTimeMillis();
Log.d("Tiger", "Intent.ACTION_SOFT_"+keyCode+"_PRESSED 0="+n);
try {
KeyEvent down = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0);
KeyEvent up = new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0);
Log.d("Tiger", "Intent.ACTION_SOFT_"+keyCode+"_PRESSED 1="+(System.currentTimeMillis()/*-n*/));
IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
Log.d("Tiger", "Intent.ACTION_SOFT_"+keyCode+"_PRESSED 2="+(System.currentTimeMillis()/*-n*/));
wm.injectKeyEvent(down, false);
Log.d("Tiger", "Intent.ACTION_SOFT_"+keyCode+"_PRESSED 3="+(System.currentTimeMillis()/*-n*/));
wm.injectKeyEvent(up, false);
Log.d("Tiger", "Intent.ACTION_SOFT_"+keyCode+"_PRESSED 4="+(System.currentTimeMillis()/*-n*/));
} catch (RemoteException e) {
Log.i("Input", "DeadOjbectException");
}
}
};
/* End : ADDED by TigerPan 20100831 */
5.避免在按下這幾個按鈕時,觸發下拉Notification視圖,影響效能
修改onInterceptTouchEvent(MotionEvent event)函數
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
/* Begin : Modified by TigerPan */
if (keysLayout.getRight() < event.getX())
return mService.interceptTouchEvent(event) ? true : super.onInterceptTouchEvent(event);
/*int parentLeft = mStatusIcons.getLeft();
android.util.Log.i("Tiger","....."+(event.getX() < (parentLeft + iconVolDown.getLeft()) || event.getX() > (parentLeft + iconHome.getRight())));
if(event.getX() < (parentLeft + iconVolDown.getLeft()) || event.getX() > (parentLeft + iconHome.getRight()))
return mService.interceptTouchEvent(event) ? true : super.onInterceptTouchEvent(event);
*/
return false;
/* End : Modified by TigerPan */
}
這樣,基本上就完成了。
編譯一下
~/donut$ source ./env.sh
~/donut$ make update-api
~/donut$ make –j8
~/donut$ emulator –skin WVGA800
~/donut$ source ./env.sh
~/donut$ make update-api
~/donut$ make –j8
~/donut$ emulator –skin WVGA800