Android應用隱藏導航欄

應用隱藏導航欄

工具類

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)起輸入法 用于隱藏輸入法后隱藏導航欄
    public static void hideWhenSystemUiVisible(View v){
        v.setOnSystemUiVisibilityChangeListener(visibility -> {
            if(visibility==View.SYSTEM_UI_FLAG_VISIBLE){
                hideBottomUIMenu(v);
            }
        });
    }

    /**
     *spinner里也有popwindow 會調(diào)起導航欄 
     * @param spinner 嘗試隱藏spinner彈出時的導航欄 
     */
    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);
        /**
         * 項目中的CartView 當作普同fragment使用  不會創(chuàng)建dialog
         */
        if (getShowsDialog()) {
            //not focus 來避免瞬間彈出
            getDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
            HideNavBarUtil.hideWhenSystemUiVisible(getDialog().getWindow().getDecorView());
            HideNavBarUtil.hideBottomUIMenu(getDialog().getWindow().getDecorView());
            //重新設置可獲取焦點 避免彈不出鍵盤
             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 來避免瞬間彈出
        setFocusable(false);
        //這里高設置MATCH_PARENT 默認WRAP 避免下層的activity顯示上來 
        setHeight(WindowManager.LayoutParams.MATCH_PARENT);
        super.showAtLocation(parent, gravity, x, y);
        final View contentView = getContentView();
        HideNavBarUtil.hideBottomUIMenu(contentView);
        setFocusable(true);
        update();
    }

image-20190222104734937.png

image-20190222104900143.png

DecorView重寫了onApplyWindowInsets方法

WindowInsets分發(fā)機制:從頂層view開始分發(fā) 直到其中的mSystemWindowInsets 和mStableInsets 被消費則完成分發(fā)

DecorView的updateColorViews方法會根據(jù)設置的systemUiVisibility 判斷是否消耗導航欄 通過設置mContentRoot的margin值(嘗試改這個margin值 可以看到content與導航欄狀態(tài)欄距離就會) ,導航欄的和狀態(tài)欄的顏色及動畫可以看updateColorViewInt方法中的邏輯

View的 fitSystemWindowsInt方法,如果view 設置了FITS_SYSTEM_WINDOWS 會去計算padding值 設置View的padding(嘗試把decorview下第一個字view top改小 很明顯看到被狀態(tài)欄遮擋了一部分)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容