Android实现路径导航条,Android菜鸟之学习android源码之二(SystemUI导航栏初步认识及修改)...

涉及到系统的定制开发,不可缺少的一个就是系统导航栏和状态栏的修改,而这部分的修改通常都涉及到SyetemUI这个系统应用的修改,它的路径通常是位于platform\frameworks\base\packages\SystemUI。

先来说说导航栏的修改吧,导航栏所在的类是在\SystemUI\src\com\android\systemui\statusbar\phone\NavigationBarView.class里,这个类主要是对导航栏所有的按键如home键,最近任务键合返回键等的封装,还有提供对横屏和竖屏方向的导航栏的显示方向的方法支持,它的xml布局是res\layout\navigaton_bar.xml,这是其中的一些代码片段,

android:layout_height="match_parent"

android:layout_width="match_parent"

android:visibility="gone"

android:paddingTop="0dp"

>

android:layout_height="match_parent"

android:layout_width="match_parent"

android:orientation="vertical"

android:clipChildren="false"

android:clipToPadding="false"

android:background="#000000"

android:id="@+id/nav_buttons"

android:animateLayoutChanges="true"

>

android:layout_width="match_parent"

android:layout_height="match_parent"

android:visibility="gone">

...

android:layout_height="@dimen/navigation_key_width"

android:layout_width="match_parent"

android:src="@drawable/ic_sysbar_recent_land"

android:scaleType="center"

android:layout_weight="0"

android:visibility="gone"

android:contentDescription="@string/accessibility_recent"

/>

...

android:layout_height="@dimen/navigation_key_width"

android:layout_width="match_parent"

android:src="@drawable/systemback_selector"

android:scaleType="center"

android:layout_weight="1"

systemui:keyCode="4"

android:contentDescription="@string/accessibility_back"

/>

可以看到最外面是一个frame layout,id是rot90,也就是竖屏时的布局,其实这个布局里还有一个rot0的布局,表示横屏的布局,当横屏模式时竖屏时的rot0布局是隐藏的,可以看到里面有id是back,和recent_apps的KeyButtonView,就是代表回退键,最近任务键啦,导航栏上所有的键都被封装在了KeyButtonView里了,那怎么区分是什么键呢?可以看到KeyButtonView的控件里有一个属性为systemui:keyCode,每个键的这个属性都不一样,比如上述代码的back键的keycode值就是4,如果要实现在导航栏上增加或者修改按钮的话就可以在这个xml布局上加上或者去掉了,那么这些键又是在哪里监听,方向又是怎么控制呢?又回到最前面的NavigationBarView里了,如下面的代码段,

public View getCurrentView() {

return mCurrentView;

}

public View getRecentsButton() {

return mCurrentView.findViewById(R.id.recent_apps);

}

public View getMenuButton() {

return mCurrentView.findViewById(R.id.menu);

}

public View getBackButton() {

return mCurrentView.findViewById(R.id.back);

}

public View getHomeButton() {

return mCurrentView.findViewById(R.id.home);

}

NavigationBarView里提供了对导航栏各键的获取方法,而真正的监听则是在systemui\statusbar\phone\PhoneStatusBar里,在它的start()方法里面的addNavigationBar()里,

@Override

public void start() {

...

super.start(); // calls createAndAddWindows()

...

addNavigationBar();

...

在addNavigationBar里会调用到一个prepareNavigationBarView方法,

// For small-screen devices (read: phones) that lack hardware navigation buttons

private void addNavigationBar() {

...

prepareNavigationBarView();

...

}

而prepareNavigationBarView方法就是最终的监听导航栏上各虚拟键的方法啦,

private void prepareNavigationBarView() {

mNavigationBarView.reorient();

mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);

mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);

mNavigationBarView.getRecentsButton().setLongClickable(true);

mNavigationBarView.getRecentsButton().setOnLongClickListener(mLongPressBackRecentsListener);

mNavigationBarView.getBackButton().setLongClickable(true);

mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackRecentsListener);

mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);

...

}

}

在这里就可以根据项目要求,找到对应的虚拟按键的监听器改写系统虚拟按键的监听方法了。

接下来就是导航栏方向的控制了,回到上面的prepareNavigationBarView方法体内第一个调用的方法是mNavigationBarView.reorient();就是在初始化当航栏时对整个导航栏方向的重新初始化了,实现方法是在NavigationBarView里,

public void reorient() {

final int rot = mDisplay.getRotation();

for (int i=0; i<4; i++) {

mRotatedViews[i].setVisibility(View.GONE);

}

mCurrentView = mRotatedViews[rot];

mCurrentView.setVisibility(View.VISIBLE);

...

可以看到,首先从Display这个静态类里获取到一个rot值,mCurrentView表示当前显示的是横屏模式还是竖屏模式,它由mRotatedViews[rot]决定,这个mRotatedViews数组里面又有什么东西呢?这个数组是在NavigationBarView加载完成后调用的onFinishInflate()方法里被初始化的,

@Override

public void onFinishInflate() {

mRotatedViews[Surface.ROTATION_0] =

mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);

mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);

mRotatedViews[Surface.ROTATION_270] = mRotatedViews[Surface.ROTATION_90];

mCurrentView = mRotatedViews[Surface.ROTATION_90];

...

}

Surface.ROTATION_0的值是0,Surface.ROTATION_90是1,以此类推,这里很眼熟吧,定义了横屏时使用rot0的布局,竖屏时使用rot90的布局,并且mCurrentView默认是90度也就是竖屏模式,如果需要改变默认的导航栏方向也可以从这方 面着手哦。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值