关闭

如何Android中自定义Navigationbar

558人阅读 评论(0) 收藏 举报

在如何控制android系统中NavigationBar 的显示与隐藏文章里简要地介绍了Navigationbar的背景知识,

NavigationBar的代码是放在... rameworksasepackagesSystemUI路径下面的。该路径下的工程主要负责手机中系统级UI的显示部分,如下图框中选中部分(包含其中的通知栏的显示),USB的连接,截屏等等。

\

NavigationBar的创建

navigationbar 的代码是在SystemUI工程SystemUI/src/com/android/systemui/statusbar/phone的路径下,其中navigationbar是由PhoneStatusBar.java类创建的。在该类的makeStatusBarView()方法下,可以看到创建Navigationbar的过程:

 

01.try {
02.boolean showNav = mWindowManagerService.hasNavigationBar();
03./// M: Support Smartbook Feature.
04.if (true) Log.v(TAG, "hasNavigationBar=" + showNav);
05.if (showNav) {
06.mNavigationBarView =
07.(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
08. 
09.mNavigationBarView.setDisabledFlags(mDisabled);
10.mNavigationBarView.setBar(this);
11.mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
12.@Override
13.public boolean onTouch(View v, MotionEvent event) {
14.checkUserAutohide(v, event);
15.return false;
16.}});
17.}
18.} catch (RemoteException ex) {
19.// no window manager? good luck with that
20.}
WindowManagerService通过判断是否需要显示NavigationBar来决定是否需要创建NavigationBarView, NavigationBarView即为我们看到视图的view了,navigation_bar即为NavigationBarView实例化的layout,你可以在SystemUI工程下的layout文件夹下找到。

 

通过修改navigation_bar布局的方式来自定义NavigationBar的UI。在该layout文件中有这样一个类。com.android.systemui.statusbar.policy.KeyButtonView,它是系统定义的在NavigationBar上的按钮类(后面会讲到),点击会产生波纹的效果。

NavigationBarView主负责UI的初始化工作,实例化布局,根据屏幕方向先取正确的图片。

NavigationBar按钮的事件绑定

NavigationBar按钮上的事件绑定并不是在NavigationBarView里实现,而是在SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java类中完成的。

通过NavigationBarView对外提供的获取按钮接口来完成按钮的绑定:

Recent, Home, SearchLight按钮事件的绑定

 

01.private void prepareNavigationBarView() {
02.mNavigationBarView.reorient();
03. 
04.mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
05.mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
06.mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
07.mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
08.updateSearchPanel();
09.}

 

Menu, Home, Back按钮事件的绑定:

 

上面三个按钮都是KeyButtonView类,它们的事件响应过程都是在类本身里面完成的。它们通过onTouchEvent()方法来响应点击事件,

 

01.public boolean onTouchEvent(MotionEvent ev) {
02.final int action = ev.getAction();
03.int x, y;
04. 
05.switch (action) {
06.case MotionEvent.ACTION_DOWN:
07.//Slog.d("KeyButtonView", "press");
08.mDownTime = SystemClock.uptimeMillis();
09.setPressed(true);
10.if (mCode != 0) {
11.sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
12.} else {
13.// Provide the same haptic feedback that the system offers for virtual keys.
14.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
15.}
16.if (mSupportsLongpress) {
17.removeCallbacks(mCheckLongPress);
18.postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
19.}
20.break;
21.case MotionEvent.ACTION_MOVE:
22.x = (int)ev.getX();
23.y = (int)ev.getY();
24.setPressed(x >= -mTouchSlop
25.&& x < getWidth() + mTouchSlop
26.&& y >= -mTouchSlop
27.&& y < getHeight() + mTouchSlop);
28.break;
29.case MotionEvent.ACTION_CANCEL:
30.setPressed(false);
31.if (mCode != 0) {
32.sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
33.}
34.if (mSupportsLongpress) {
35.removeCallbacks(mCheckLongPress);
36.}
37.break;
38.case MotionEvent.ACTION_UP:
39.final boolean doIt = isPressed();
40.setPressed(false);
41.if (mCode != 0) {
42.if (doIt) {
43.sendEvent(KeyEvent.ACTION_UP, 0);
44.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
45.playSoundEffect(SoundEffectConstants.CLICK);
46.} else {
47.sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
48.}
49.} else {
50.// no key code, just a regular ImageView
51.if (doIt) {
52.performClick();
53.}
54.}
55.if (mSupportsLongpress) {
56.removeCallbacks(mCheckLongPress);
57.}
58.break;
59.}
60. 
61.return true;
62.}

mCode是用来判断该触摸是来自于哪个button,表示不同button的keycode在KeyEvent中类都有定义。该值在布局文件中通过获取navigationbar_view中的systemui:keycode属性来获得,下面是layout布局文件中back相应代码段:

 

 

01.<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
02.android:layout_width="@dimen/navigation_key_width"
03.android:layout_height="match_parent"
04.android:src="@drawable/ic_sysbar_back"
05.systemui:keyCode="4"
06.android:layout_weight="0"
07.android:scaleType="center"
08.systemui:glowBackground="@drawable/ic_sysbar_highlight"
09.android:contentDescription="@string/accessibility_back"
10./>

在onTouch中方法通过sendEvent()方法来执行不同的keycode响应事件,该方法会创建一个包含keycode的KeyEvent对象封装,然后通过injectInputEvent()向InputManager插入一个事件,再发送出去。


http://www.it165.net/pro/html/201503/35530.html

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:134265次
    • 积分:1931
    • 等级:
    • 排名:千里之外
    • 原创:37篇
    • 转载:147篇
    • 译文:0篇
    • 评论:4条
    最新评论