如何Android中自定義Navigationbar
來(lái)源:程序員人生 發(fā)布時(shí)間:2015-03-16 10:42:18 閱讀次數(shù):7164次
在如何控制android系統(tǒng)中NavigationBar 的顯示與隱藏文章里扼要地介紹了Navigationbar的背景知識(shí),
NavigationBar的代碼是放在...frameworksasepackagesSystemUI路徑下面的。該路徑下的工程主要負(fù)責(zé)手機(jī)中系統(tǒng)級(jí)UI的顯示部份,以下圖框當(dāng)選中部份(包括其中的通知欄的顯示),USB的連接,截屏等等。

NavigationBar的創(chuàng)建
navigationbar 的代碼是在SystemUI工程SystemUI/src/com/android/systemui/statusbar/phone的路徑下,其中navigationbar是由PhoneStatusBar.java類(lèi)創(chuàng)建的。在該類(lèi)的makeStatusBarView()方法下,可以看到創(chuàng)建Navigationbar的進(jìn)程:
try {
boolean showNav = mWindowManagerService.hasNavigationBar();
/// M: Support Smartbook Feature.
if (true) Log.v(TAG, "hasNavigationBar=" + showNav);
if (showNav) {
mNavigationBarView =
(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
mNavigationBarView.setDisabledFlags(mDisabled);
mNavigationBarView.setBar(this);
mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
checkUserAutohide(v, event);
return false;
}});
}
} catch (RemoteException ex) {
// no window manager? good luck with that
}
WindowManagerService通過(guò)判斷是不是需要顯示NavigationBar來(lái)決定是不是需要?jiǎng)?chuàng)建NavigationBarView, NavigationBarView即為我們看到視圖的view了,navigation_bar即為NavigationBarView實(shí)例化的layout,你可以在SystemUI工程下的layout文件夾下找到。
通過(guò)修改navigation_bar布局的方式來(lái)自定義NavigationBar的UI。在該layout文件中有這樣1個(gè)類(lèi)。com.android.systemui.statusbar.policy.KeyButtonView,它是系統(tǒng)定義的在NavigationBar上的按鈕類(lèi)(后面會(huì)講到),點(diǎn)擊會(huì)產(chǎn)生波紋的效果。
NavigationBarView主負(fù)責(zé)UI的初始化工作,實(shí)例化布局,根據(jù)屏幕方向先取正確的圖片。
NavigationBar按鈕的事件綁定
NavigationBar按鈕上的事件綁定其實(shí)不是在NavigationBarView里實(shí)現(xiàn),而是在SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java類(lèi)中完成的。
通過(guò)NavigationBarView對(duì)外提供的獲得按鈕接口來(lái)完成按鈕的綁定:
Recent, Home, SearchLight按鈕事件的綁定
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
updateSearchPanel();
}
Menu, Home, Back按鈕事件的綁定:
上面3個(gè)按鈕都是KeyButtonView類(lèi),它們的事件響應(yīng)進(jìn)程都是在類(lèi)本身里面完成的。它們通過(guò)onTouchEvent()方法來(lái)響應(yīng)點(diǎn)擊事件,
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
int x, y;
switch (action) {
case MotionEvent.ACTION_DOWN:
//Slog.d("KeyButtonView", "press");
mDownTime = SystemClock.uptimeMillis();
setPressed(true);
if (mCode != 0) {
sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
} else {
// Provide the same haptic feedback that the system offers for virtual keys.
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
if (mSupportsLongpress) {
removeCallbacks(mCheckLongPress);
postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
}
break;
case MotionEvent.ACTION_MOVE:
x = (int)ev.getX();
y = (int)ev.getY();
setPressed(x >= -mTouchSlop
&& x < getWidth() + mTouchSlop
&& y >= -mTouchSlop
&& y < getHeight() + mTouchSlop);
break;
case MotionEvent.ACTION_CANCEL:
setPressed(false);
if (mCode != 0) {
sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
}
if (mSupportsLongpress) {
removeCallbacks(mCheckLongPress);
}
break;
case MotionEvent.ACTION_UP:
final boolean doIt = isPressed();
setPressed(false);
if (mCode != 0) {
if (doIt) {
sendEvent(KeyEvent.ACTION_UP, 0);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
playSoundEffect(SoundEffectConstants.CLICK);
} else {
sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
}
} else {
// no key code, just a regular ImageView
if (doIt) {
performClick();
}
}
if (mSupportsLongpress) {
removeCallbacks(mCheckLongPress);
}
break;
}
return true;
}
mCode是用來(lái)判斷該觸摸是來(lái)自于哪一個(gè)button,表示不同button的keycode在KeyEvent中類(lèi)都有定義。該值在布局文件中通過(guò)獲得navigationbar_view中的systemui:keycode屬性來(lái)取得,下面是layout布局文件中back相應(yīng)代碼段:
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="0"
android:scaleType="center"
systemui:glowBackground="@drawable/ic_sysbar_highlight"
android:contentDescription="@string/
accessibility_back"
/>
在onTouch中方法通過(guò)sendEvent()方法來(lái)履行不同的keycode響應(yīng)事件,該方法會(huì)創(chuàng)建1個(gè)包括keycode的KeyEvent對(duì)象封裝,然后通過(guò)injectInputEvent()向InputManager插入1個(gè)事件,再發(fā)送出去。
生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)