如图,需求是增加一个按钮可以隐藏NavigationBar,上滑显示NavigationBar。
参考文章:
Android 8.1平台客制化虚拟导航按键
Android 7.0 虚拟按键(NavigationBar)源码分析(一) 之 View的创建流程
android导航栏隐藏与浮现
1.首先新建一个hide_show.xml,其中systemui:keyCode="142"为事件值,相当与F12.
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。