系統(tǒng)狀態(tài)欄與底部導(dǎo)航欄相關(guān)工具類

/**
 * 系統(tǒng)狀態(tài)欄與底部導(dǎo)航欄相關(guān)工具類
 * <p>僅在 SDK >= 4.4 時(shí)有效</p>
 * <p>本工具類共分兩種模式:著色模式{@link #setDisplayOption} 和 全透明模式{@link #fullTransparentBar}</p>
 */
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public final class SystemBarUtil {
    private static final String TAG_STATUS_BAR = "StatusBar";
    private static final String TAG_NAVIGATION_BAR = "NavigationBar";
    /* 無效的顏色值 */
    private static final int INVALID_VAL = -1;
    /* 默認(rèn)的狀態(tài)欄顏色 */
    private static final int DEFAULT_STATUS_COLOR = 0x10000000;
    /* 默認(rèn)的底部導(dǎo)航欄顏色 */
    private static final int DEFAULT_NAVIGATION_COLOR = Color.TRANSPARENT;

    private SystemBarUtil() {
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    /***********************************************************************************************
     ****  沉浸式系統(tǒng)欄(狀態(tài)欄與導(dǎo)航欄)邀跃,著色模式霉咨,不可全透明(sdk >= 4.4)
     **********************************************************************************************/
    /**
     * 設(shè)置狀態(tài)欄和底部導(dǎo)航欄的顯示方式
     *
     * @param activity        activity
     * @param fitSystemWindow {@code true}: 內(nèi)容不會(huì)顯示到狀態(tài)欄和導(dǎo)航欄上<br>{@code false}: 內(nèi)容顯示到狀態(tài)欄和導(dǎo)航欄上
     * @param clipToPadding   {@code true}: 裁剪 padding 區(qū)域,padding 區(qū)域不可使用<br>{@code false}: 不裁剪 padding 區(qū)域,padding 區(qū)域可使用
     */
    public static void setDisplayOption(@NonNull Activity activity, boolean fitSystemWindow, boolean clipToPadding) {
        // 獲取根布局
        ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
        rootView.setClipToPadding(clipToPadding);
        rootView.setFitsSystemWindows(fitSystemWindow);
    }

    /**
     * 設(shè)置頂部狀態(tài)欄
     *
     * @param activity
     * @param color    設(shè)置頂部狀態(tài)欄的顏色
     */
    public static void setupStatusBar(@NonNull Activity activity, @ColorInt int color) {
        int statusHeight = ScreenUtil.getStatusBarHeight();
        int statusColor = DEFAULT_STATUS_COLOR;
        if (color != INVALID_VAL) {
            statusColor = color;
        }
        // 設(shè)置狀態(tài)欄透明
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        // 防止重復(fù)添加 statusBarView
        removeStatusBarView(decorView);
        // 繪制一個(gè)和狀態(tài)欄一樣高的矩形 View
        View statusBarView = createStatusBarView(activity, statusHeight, statusColor);
        // 添加 statusBarView 到整個(gè)Window的最頂層布局中,這里的 statusBarView 只是作為狀態(tài)欄的背景,
        // 它的 visible 不能影響到狀態(tài)欄的 visible
        decorView.addView(statusBarView);
    }

    /**
     * 繪制一個(gè)和狀態(tài)欄一樣高的矩形View
     *
     * @param activity
     * @param statusHeight 繪制的矩形的高度
     * @param statusColor  繪制的矩形的顏色
     * @return 繪制的矩形 View
     */
    private static View createStatusBarView(@NonNull Activity activity, int statusHeight, @ColorInt int statusColor) {
        View statusBarView = new View(activity);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, statusHeight);
        params.gravity = Gravity.TOP;
        statusBarView.setLayoutParams(params);
        statusBarView.setBackgroundColor(statusColor);
        statusBarView.setTag(TAG_STATUS_BAR);
        return statusBarView;
    }

    /**
     * 移除已經(jīng)存在的 statusBarView
     *
     * @param decorView
     */
    private static void removeStatusBarView(@NonNull ViewGroup decorView) {
        View statusBarView = decorView.findViewWithTag(TAG_STATUS_BAR);
        if (statusBarView != null) {
            decorView.removeView(statusBarView);
        }
    }

    /**
     * 設(shè)置狀態(tài)欄的透明度
     *
     * @param activity
     * @param alpha    透明度(0-1)
     */
    public static void setStatusBarAlpha(@NonNull Activity activity, @FloatRange(from = 0, to = 1) float alpha) {
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        View statusView = decorView.findViewWithTag(TAG_STATUS_BAR);
        if (statusView != null) {
            statusView.setAlpha(alpha);
        }
    }

    /**
     * 設(shè)置狀態(tài)欄的顯示和隱藏
     *
     * @param activity
     * @param isShow   {@code true}: 顯示<br>{@code false}: 隱藏
     */
    public static void showStatusBar(@NonNull Activity activity, boolean isShow) {
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        View statusView = decorView.findViewWithTag(TAG_STATUS_BAR);
        if (isShow) {
            if (statusView != null) {
                statusView.setVisibility(View.VISIBLE);
            }
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        } else {
            if (statusView != null) {
                statusView.setVisibility(View.GONE);
            }
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
    }

    /**
     * 設(shè)置底部導(dǎo)航欄
     *
     * @param activity
     * @param color    底部導(dǎo)航欄的顏色
     */
    public static void setupNavBar(@NonNull Activity activity, @ColorInt int color) {
        if (ScreenUtil.hasNavigationBar()) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            int navHeight = ScreenUtil.getNavBarHeight();
            int navColor = DEFAULT_NAVIGATION_COLOR;
            if (color != INVALID_VAL) {
                navColor = color;
            }
            ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
            removeNavBarView(decorView);
            View navBarView = createNavBarView(activity, navHeight, navColor);
            decorView.addView(navBarView);
        }
    }

    /**
     * 繪制一個(gè)和底部導(dǎo)航欄一樣高的矩形 View
     *
     * @param activity
     * @param navHeight 繪制的矩形的高度
     * @param navColor  繪制的矩形的顏色
     * @return 繪制的矩形 View
     */
    private static View createNavBarView(@NonNull Activity activity, int navHeight, @ColorInt int navColor) {
        View navBarView = new View(activity);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, navHeight);
        params.gravity = Gravity.BOTTOM;
        navBarView.setLayoutParams(params);
        navBarView.setBackgroundColor(navColor);
        navBarView.setTag(TAG_NAVIGATION_BAR);
        return navBarView;
    }

    /**
     * 移除已經(jīng)存在的 navBarView
     *
     * @param decorView
     */
    private static void removeNavBarView(@NonNull ViewGroup decorView) {
        View navBarView = decorView.findViewWithTag(TAG_NAVIGATION_BAR);
        if (navBarView != null) {
            decorView.removeView(navBarView);
        }
    }

    /**
     * 設(shè)置底部導(dǎo)航欄的透明度
     *
     * @param activity
     * @param alpha    透明度(0-1)
     */
    public static void setNavBarAlpha(@NonNull Activity activity, @FloatRange(from = 0, to = 1) float alpha) {
        if (ScreenUtil.hasNavigationBar()) {
            ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
            View navBarView = decorView.findViewWithTag(TAG_NAVIGATION_BAR);
            if (navBarView != null) {
                navBarView.setAlpha(alpha);
            }
        }
    }

    /**
     * 設(shè)置底部導(dǎo)航欄的顯示和隱藏
     *
     * @param activity activity
     * @param isShow   {@code true}: 顯示<br>{@code false}: 隱藏
     */
    public static void showNavBar(@NonNull Activity activity, boolean isShow) {
        if (ScreenUtil.hasNavigationBar()) {
            View decorView = activity.getWindow().getDecorView();
            if (isShow) {
                decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            } else {
                decorView.setSystemUiVisibility(View.INVISIBLE);
            }
        }
    }

    /***********************************************************************************************
     ****  沉浸式系統(tǒng)欄(狀態(tài)欄與導(dǎo)航欄)崎坊,全透明模式向臀,(sdk >= 5.0)
     **********************************************************************************************/
    /**
     * 設(shè)置系統(tǒng)欄全透明
     *
     * @param activity
     * @param statusBar 狀態(tài)欄是否全透明
     * @param navBar    導(dǎo)航欄是否全透明
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public static void fullTransparentBar(Activity activity, boolean statusBar, boolean navBar) {
        Window window = activity.getWindow();
        window.clearFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        if (statusBar && navBar) {
            window.getDecorView().setSystemUiVisibility(
                    // 全屏顯示撬槽,但狀態(tài)欄不會(huì)被隱藏覆蓋,狀態(tài)欄依然可見,Activity 頂端布局部分會(huì)被狀態(tài)遮住
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            // 隱藏導(dǎo)航欄
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            // 防止系統(tǒng)欄隱藏時(shí)內(nèi)容區(qū)域大小發(fā)生變化
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
            window.setNavigationBarColor(Color.TRANSPARENT);
        } else if (statusBar && !navBar) {
            window.getDecorView().setSystemUiVisibility(
                    // 全屏顯示,但狀態(tài)欄不會(huì)被隱藏覆蓋星爪,狀態(tài)欄依然可見,Activity 頂端布局部分會(huì)被狀態(tài)遮住
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            // 防止系統(tǒng)欄隱藏時(shí)內(nèi)容區(qū)域大小發(fā)生變化
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        } else if (!statusBar && navBar) {
            window.getDecorView().setSystemUiVisibility(
                    // 全屏顯示粉私,但狀態(tài)欄不會(huì)被隱藏覆蓋顽腾,狀態(tài)欄依然可見,Activity 頂端布局部分會(huì)被狀態(tài)遮住
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            // 隱藏導(dǎo)航欄
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            // 防止系統(tǒng)欄隱藏時(shí)內(nèi)容區(qū)域大小發(fā)生變化
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setNavigationBarColor(Color.TRANSPARENT);
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诺核,一起剝皮案震驚了整個(gè)濱河市抄肖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌猪瞬,老刑警劉巖憎瘸,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異陈瘦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)潮售,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門痊项,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人酥诽,你說我怎么就攤上這事鞍泉。” “怎么了肮帐?”我有些...
    開封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵咖驮,是天一觀的道長边器。 經(jīng)常有香客問我,道長托修,這世上最難降的妖魔是什么忘巧? 我笑而不...
    開封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮睦刃,結(jié)果婚禮上砚嘴,老公的妹妹穿的比我還像新娘。我一直安慰自己涩拙,他們只是感情好际长,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兴泥,像睡著了一般工育。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上搓彻,一...
    開封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天如绸,我揣著相機(jī)與錄音,去河邊找鬼好唯。 笑死竭沫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的骑篙。 我是一名探鬼主播蜕提,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼靶端!你這毒婦竟也來了谎势?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤杨名,失蹤者是張志新(化名)和其女友劉穎脏榆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體台谍,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡须喂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了趁蕊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坞生。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖掷伙,靈堂內(nèi)的尸體忽然破棺而出是己,到底是詐尸還是另有隱情,我是刑警寧澤任柜,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布卒废,位于F島的核電站沛厨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏摔认。R本人自食惡果不足惜逆皮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望级野。 院中可真熱鬧页屠,春花似錦、人聲如沸蓖柔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽况鸣。三九已至牢贸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間镐捧,已是汗流浹背潜索。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留懂酱,地道東北人竹习。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像列牺,于是被迫代替她去往敵國和親整陌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容