一、android系统的底部导航栏效果如下图,我们这里要实现底部虚拟按钮NavigationBar的点击隐藏与滑动显示的功能。
二、先来看看最后实现的效果图,真机测试效果。
三、实现步骤:
1、添加布局文件frameworks/base/packages/SystemUI/res/layout/hide_show.xml ,内容如下,systemui:keyCode="142"是表示点击该按钮发送142的按键值。
2、系统通过方法getDefaultLayout()去获取config_navBarLayout里面包含的几个虚拟按钮,所在的文件路径是frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
3、找到包含有config_navBarLayout所有config.xml,我这里是
frameworks/base/packages/SystemUI/res/values-sw372dp/config.xml
frameworks/base/packages/SystemUI/res/values-sw600dp/config.xml
frameworks/base/packages/SystemUI/res/values-sw900dp/config.xml
在字符串config_navBarLayout里面添加hide
4、frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java里面添加一个全局变量public static final String HIDE = "hide";然后在createView函数里面添加
else if (HIDE.equals(button)){// add by wfh for hide navigationBar
v = inflater.inflate(R.layout.hide_show, parent, false);
}
相应的修改如下图:
5、接下来修改frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
5.1 添加一个变量
private KeyButtonDrawable mHideIcon;
5.2 添加一个公共方法
public ButtonDispatcher getHideButton() {
return mButtonDispatchers.get(R.id.hide);
}
5.3 添加mButtonDispatchers.put(R.id.hide, new ButtonDispatcher(R.id.hide))去put我们自定义的hide布局按钮。
mButtonDispatchers.put(R.id.hide, new ButtonDispatcher(R.id.hide));
5.4 在updateIcons方法里添加mHideIcon= getDrawable(ctx, R.drawable.ic_sysbar_back_ime, R.drawable.ic_sysbar_back_ime_dark);获取png图像资源,在drawable-hdpi下添加ic_sysbar_back_ime.png和ic_sysbar_back_ime_dark.png两种图片。
mHideIcon= getDrawable(ctx, R.drawable.ic_sysbar_back_ime, R.drawable.ic_sysbar_back_ime_dark);
5.5 在setNavigationIconHints方法里面添加getHideButton().setImageDrawable(mHideIcon);
getHideButton().setImageDrawable(mHideIcon);
5.6 在setNavigationIconHints方法里面添加getHideButton().setImageDrawable(mHideIcon);
getHideButton().setImageDrawable(mHideIcon);
5.7 NavigationBarView.java文件里面相应的修改点如下图:
6、处理点击隐藏按钮事件,发送一个HIDE_NAVIGATION_BAR广播,frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java文件里面的interceptKeyBeforeDispatching方法添加如下代码:
else if(keyCode == KeyEvent.KEYCODE_F12){// added by wfh
Intent hideNavigationBarIntent = new Intent("HIDE_NAVIGATION_BAR");
mContext.sendBroadcast(hideNavigationBarIntent);
return -1;
}
7、处理上滑显示导航栏事件,在SystemGesturesPointerEventListener里面添加如下代码侦测上滑事件发送广播SHOW_NAVIGATION_BAR。
Intent showNavigationBarIntent = new Intent("SHOW_NAVIGATION_BAR");
mContext.sendBroadcast(showNavigationBarIntent);
8、最后在frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java里面接收广播,隐藏和显示导航栏。private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver()里面添加如下代码处理接收到的广播。
}else if(action.equals("HIDE_NAVIGATION_BAR")&&mWindowManager!=null&&mNavigationBarView!=null){
if (DEBUG) Log.v(TAG, "onReceive: HIDE_NAVIGATION_BAR");
if("1".equals(SystemProperties.get("persist.user.hide_nav"))){
mWindowManager.removeView(mNavigationBarView);//
SystemProperties.set("persist.user.hide_nav","0");
Toast toast = Toast.makeText(mContext,"you can show the navigation bar by swiping from bottom!", Toast.LENGTH_LONG);
toast.show();
}
}else if(action.equals("SHOW_NAVIGATION_BAR")){
if (DEBUG) Log.v(TAG, "onReceive: SHOW_NAVIGATION_BAR");
if("0".equals(SystemProperties.get("persist.user.hide_nav"))){
SystemProperties.set("persist.user.hide_nav","1");
if(mNavigationBarView==null) {
createNavigationBar();
}else
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
}
}
9、大概就这样,功能是实现了,大家根据自己的实际情况优化了。
四、整个过程修改的完整源码包下载路径:https://download.csdn.net/download/qq_37858386/12334647
包含下面几个文件:
frameworks/base/packages/SystemUI/res/values-sw372dp/config.xml
frameworks/base/packages/SystemUI/res/values-sw600dp/config.xml
frameworks/base/packages/SystemUI/res/values-sw900dp/config.xml
frameworks/base/packages/SystemUI/res/values/config.xml
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java