如图,需求是增加一个按钮可以隐藏NavigationBar,上滑显示NavigationBar。
参考文章:
Android 7.0 虚拟按键(NavigationBar)源码分析(一) 之 View的创建流程
1.首先新建一个hide_show.xml,其中systemui:keyCode="142"为事件值,相当与F12.
<?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"
android:src="@drawable/ic_sysbar_back_ime"
systemui:keyCode="142"
android:scaleType="center"
android:contentDescription="@string/accessibility_home"
android:paddingStart="@dimen/navigation_key_padding"
android:paddingEnd="@dimen/navigation_key_padding"
/>
2.NavigationBarInflaterView.java
增加hide。
public static final String HOME = "home";
public static final String RECENT = "recent";
public static final String NAVSPACE = "space";
public static final String CLIPBOARD = "clipboard";
public static final String KEY = "key";
public static final String HIDE = "hide";// add by csc for hide navigationbar
/// M: BMW @{
public static final String RESTORE = "restore";
protected void inflateLayout(String newLayout) {
mCurrentLayout = newLayout;
if (newLayout == null) {
newLayout = getDefaultLayout();
}
newLayout = "hide;recent;home;back";// add by csc
String[] sets = newLayout.split(GRAVITY_SEPARATOR, 4);// mod by csc from 3
String[] hide = sets[0].split(BUTTON_SEPARATOR);// add by csc
String[] start = sets[1].split(BUTTON_SEPARATOR);
String[] center = sets[2].split(BUTTON_SEPARATOR);
String[] end = sets[3].split(BUTTON_SEPARATOR);
// Inflate these in start to end order or accessibility traversal will be messed up.
inflateButtons(hide, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);// add by csc
inflateButtons(hide, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);// add by csc
inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);
inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);
inflateButtons(center, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);
inflateButtons(center, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);
// delete by csc
/* addGravitySpacer((LinearLayout) mRot0.findViewById(R.id.ends_group));
addGravitySpacer((LinearLayout) mRot90.findViewById(R.id.ends_group));*/
inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);
inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);
}
其中,为了布局把center_group改为ends_group,将space去掉(注释addGravitySpacer)。
inflateButton方法里面增加:
else if (HIDE.equals(button)){// add by csc for hide navigationBar
Log.d("chenshichun"," "+this.getClass().getCanonicalName()+" ::::::HIDE:button::");
v = inflater.inflate(R.layout.hide_show, parent, false);
}
3.NavigationBarView.java
mBarTransitions = new NavigationBarTransitions(this);
mButtonDisatchers.put(R.id.hide, new ButtonDispatcher(R.id.hide));// add by csc for hide navigationbar
getHideButton().setLongClickable(false);// add by csc for hide navigationbar
mButtonDisatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
mButtonDisatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
mButtonDisatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
public ButtonDispatcher getBackButton() {
return mButtonDisatchers.get(R.id.back);
}
public ButtonDispatcher getHomeButton() {
return mButtonDisatchers.get(R.id.home);
}
public ButtonDispatcher getHideButton() {// add by csc
return mButtonDisatchers.get(R.id.hide);
}
到这里可以在界面上显示按钮。接下来加上点击事件。
4.PhoneWindowManager.java
在interceptKeyBeforeDispatching方法里面增加F12的监听事件,这时候为隐藏事件:
else if(keyCode == KeyEvent.KEYCODE_F12){// add by csc
Intent hideNavigationBarIntent = new Intent("HIDE_NAVIGATION_BAR");
mContext.sendBroadcast(hideNavigationBarIntent);
return -1;
}
上滑显示事件:
mSystemGestures = new SystemGesturesPointerEventListener(context,
new SystemGesturesPointerEventListener.Callbacks() {
@Override
public void onSwipeFromTop() {
/// M: Disable gesture in immersive mode. {@
if (isGestureIsolated()) {
return;
}
/// @}
if (mStatusBar != null) {
requestTransientBars(mStatusBar);
}
}
@Override
public void onSwipeFromBottom() {
/// M: Disable gesture in immersive mode. {@
if (isGestureIsolated()) {
return;
}
/// @}
if (mNavigationBar != null && mNavigationBarOnBottom) {
requestTransientBars(mNavigationBar);
}
/*add by csc*/
Intent intent = new Intent();
intent.setAction("SHOW_NAVIGATION_BAR");
mContext.sendBroadcast(intent);
}
5.PhoneStatusBar.java
该类处理导航栏的隐藏或显示。
先注册广播:
filter.addAction("HIDE_NAVIGATION_BAR");// add by csc
filter.addAction("SHOW_NAVIGATION_BAR");// add by csc
else if(action.equals("HIDE_NAVIGATION_BAR")&&mWindowManager!=null&&mNavigationBarView!=null&&mNavigationBarView.getParent()!=null){
mWindowManager.removeView(mNavigationBarView);
mNavigationBarView = null ;
isNavigationShow = false;
}else if(action.equals("SHOW_NAVIGATION_BAR")){
if(isNavigationShow){
return ;
}
showNavigationBar();
isNavigationShow = true;
}
public void showNavigationBar() {
mNavigationBarView =(NavigationBarView) View.inflate(mContext, R.layout.navigation_bar, null);
prepareNavigationBarView();
addNavigationBar();
//防止在桌面时上拉出导航栏时,导航栏背景为黑色
mNavigationBarView.setBackgroundColor(Color.TRANSPARENT);
}
protected void addNavigationBar() {
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
if (mNavigationBarView == null) return;
prepareNavigationBarView();
if(mNavigationBarView!=null && mNavigationBarView.getParent()==null) {// add by csc
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
}
}
ok。