應(yīng)用隱藏導(dǎo)航欄
工具類
public class HideNavBarUtil {
public static void hideBottomUIMenu(View v) {
//隱藏虛擬按鍵抖苦,并且全屏
if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
v.setSystemUiVisibility(View.GONE);
} else if (Build.VERSION.SDK_INT >= 19) {
//for new api versions.
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY ;
v.setSystemUiVisibility(uiOptions);
}
}
//調(diào)起輸入法 用于隱藏輸入法后隱藏導(dǎo)航欄
public static void hideWhenSystemUiVisible(View v){
v.setOnSystemUiVisibilityChangeListener(visibility -> {
if(visibility==View.SYSTEM_UI_FLAG_VISIBLE){
hideBottomUIMenu(v);
}
});
}
/**
*spinner里也有popwindow 會(huì)調(diào)起導(dǎo)航欄
* @param spinner 嘗試隱藏spinner彈出時(shí)的導(dǎo)航欄
*/
public static void hideSpinnerSystemUi(Spinner spinner){
Field mPopup = null;
try {
mPopup = spinner.getClass().getDeclaredField("mPopup");
mPopup.setAccessible(true);
ListPopupWindow listPopupWindow = (ListPopupWindow) mPopup.get(spinner);
Field mPopup1 = listPopupWindow.getClass().getSuperclass().getDeclaredField("mPopup");
mPopup1.setAccessible(true);
PopupWindow popupWindow = (PopupWindow) mPopup1.get(listPopupWindow);
popupWindow.setFocusable(false);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Activity
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
HideNavBarUtil.hideBottomUIMenu(getWindow().getDecorView());
}
}
DialogFragment
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
/**
* 項(xiàng)目中的CartView 當(dāng)作普同fragment使用 不會(huì)創(chuàng)建dialog
*/
if (getShowsDialog()) {
//not focus 來(lái)避免瞬間彈出
getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
HideNavBarUtil.hideWhenSystemUiVisible(getDialog().getWindow().getDecorView());
HideNavBarUtil.hideBottomUIMenu(getDialog().getWindow().getDecorView());
//重新設(shè)置可獲取焦點(diǎn) 避免彈不出鍵盤
getDialog().getWindow().getDecorView().post(() -> getDialog().getWindow().setFlags(~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE));
}
}
PopWindow
@Override
public void showAtLocation(View parent, int gravity, int x, int y) {
////not focus 來(lái)避免瞬間彈出
setFocusable(false);
//這里高設(shè)置MATCH_PARENT 默認(rèn)WRAP 避免下層的activity顯示上來(lái)
setHeight(WindowManager.LayoutParams.MATCH_PARENT);
super.showAtLocation(parent, gravity, x, y);
final View contentView = getContentView();
HideNavBarUtil.hideBottomUIMenu(contentView);
setFocusable(true);
update();
}
DecorView重寫了onApplyWindowInsets方法
WindowInsets分發(fā)機(jī)制:從頂層view開(kāi)始分發(fā) 直到其中的mSystemWindowInsets 和mStableInsets 被消費(fèi)則完成分發(fā)
DecorView的updateColorViews方法會(huì)根據(jù)設(shè)置的systemUiVisibility 判斷是否消耗導(dǎo)航欄 通過(guò)設(shè)置mContentRoot的margin值(嘗試改這個(gè)margin值 可以看到content與導(dǎo)航欄狀態(tài)欄距離就會(huì)) ,導(dǎo)航欄的和狀態(tài)欄的顏色及動(dòng)畫可以看updateColorViewInt方法中的邏輯
View的 fitSystemWindowsInt方法斩启,如果view 設(shè)置了FITS_SYSTEM_WINDOWS 會(huì)去計(jì)算padding值 設(shè)置View的padding(嘗試把decorview下第一個(gè)字view top改小 很明顯看到被狀態(tài)欄遮擋了一部分)