Android 8.1实现底部虚拟按钮NavigationBar的点击隐藏与滑动显示
一、android系统的底部导航栏效果如下图,我们这里要实现底部虚拟按钮NavigationBar的点击隐藏与滑动显示的功能。
二、先来看看最后实现的效果图,真机测试效果。
三、实现步骤:
1、添加布局文件frameworks/base/packages/SystemUI/res/layout/hide_show.xml ,内容如下,systemui:keyCode="142"是表示点击该按钮发送142的按键值。
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.systemui.statusbar.policy.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/hide"
android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:layout_weight="0"
systemui:keyCode="142"
android:scaleType="center"
android:contentDescription="@string/accessibility_back"
android:paddingStart="@dimen/navigation_key_padding"
android:paddingEnd="@dimen/navigation_key_padding"
/>
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、大概就这样,功能是实现了,大家根据自己的实际情况优化了。
四、整个过程修改的完整源码包下载路径:navigationbar.zip_android8隐藏虚拟按键-Android代码类资源-CSDN下载
包含下面几个文件:
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