StatusBarUtils實(shí)現(xiàn)沉浸式狀態(tài)欄適配(第一種實(shí)現(xiàn)方式)

現(xiàn)在沉浸式狀態(tài)欄基本都成為產(chǎn)品主流樣式了瓤逼。但對(duì)于google官方提供的API對(duì)于狀態(tài)欄的顏色設(shè)置是4.4版本才推出毅人,所以我們也只能適配4.4及以上版本闯狱。但在4.4到5.0的時(shí)候只能通過(guò)設(shè)置狀態(tài)欄透明票堵,然后手動(dòng)添加偽狀態(tài)欄來(lái)進(jìn)行修改狀態(tài)欄顏色,對(duì)于5.0以上可以通過(guò)修改狀態(tài)欄顏色即可偷溺。我們都知道蹋辅,對(duì)于Activity我們通過(guò)setContentView方法添加的我們需要顯示的xlm布局文件,其實(shí)是添加在decoview下面的content(其實(shí)是一個(gè)FrameLayout)里面挫掏。對(duì)于4.4~5.0之間的版本我們創(chuàng)建的偽狀態(tài)欄就添加在decoview里面侦另。先看看效果:


statusbarutils01.png

statusbarutils02.png

看效果還行,并且以適配Drawlayout,F(xiàn)ragment對(duì)狀態(tài)欄的修改褒傅。
如果對(duì)于文字描敘不太清楚弃锐,可看看下面實(shí)現(xiàn)方式布局圖:


實(shí)現(xiàn)方式.png

廢話不多,開擼殿托、開擼霹菊。

public class StatusBarUtil {

    private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.status_bar_util_fake_status_bar_view;

    public static void setStatusBarColorRes(Activity activity, @ColorRes int color){
        setStatusBarColor(activity, activity.getResources().getColor(color));
    }

    public static void setStatusBarColor(Activity activity, @ColorInt int color) {
        DrawerLayout drawerLayout = findDrawerLayout(activity);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            if (drawerLayout == null) {
                if (activity.getWindow().getStatusBarColor() == Color.TRANSPARENT) {
                    setContentLayoutParamsOfTop(activity, getStatusBarHeight(activity));
                }
                activity.getWindow().setStatusBarColor(color);
            } else {
                activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
                setDrawLayouterStatusBarColor(activity, drawerLayout, color);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            if (drawerLayout == null) {
                ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
                View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
                if (fakeStatusBarView != null) {
                    if (fakeStatusBarView.getVisibility() == View.GONE) {
                        fakeStatusBarView.setVisibility(View.VISIBLE);
                    }
                    fakeStatusBarView.setBackgroundColor(color);
                } else {
                    decorView.addView(createStatusBarView(activity, color));
                }
                setContentLayoutParamsOfTop(activity, getStatusBarHeight(activity));
                setRootView(activity);
            } else {
                setDrawLayouterStatusBarColor(activity, drawerLayout, color);
            }
        }
    }

    public static void setStatusBarTraslucent(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            setTransparentForWindow(activity);
            setContentLayoutParamsOfTop(activity, 0);
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                clearPreviousSetting(activity);
            }
            DrawerLayout drawerLayout = findDrawerLayout(activity);
            if (drawerLayout != null) {
                setDrawerLayoutProperty(drawerLayout);
            }
        }
    }

    private static void setDrawLayouterStatusBarColor(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
        ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
        View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
        if (fakeStatusBarView != null) {
            if (fakeStatusBarView.getVisibility() == View.GONE) {
                fakeStatusBarView.setVisibility(View.VISIBLE);
            }
            fakeStatusBarView.setBackgroundColor(color);
        } else {
            drawerLayout.removeView(contentLayout);
            LinearLayout linearLayout = new LinearLayout(activity);
            linearLayout.setLayoutParams(new DrawerLayout.LayoutParams(DrawerLayout.LayoutParams.MATCH_PARENT, DrawerLayout.LayoutParams.MATCH_PARENT));
            linearLayout.setOrientation(LinearLayout.VERTICAL);
            linearLayout.addView(createStatusBarView(activity, color));
            linearLayout.addView(contentLayout);
            drawerLayout.addView(linearLayout, 0);
        }
        setDrawerLayoutProperty(drawerLayout);
    }

    private static void clearPreviousSetting(Activity activity) {
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
        if (fakeStatusBarView != null) {
            decorView.removeView(fakeStatusBarView);
        }
    }

    private static void setContentLayoutParamsOfTop(Activity activity, int top) {
        ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
        rootView.setPadding(0, top, 0, 0);
    }

    private static void setTransparentForWindow(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
            activity.getWindow()
                    .getDecorView()
                    .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow()
                    .setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    private static DrawerLayout findDrawerLayout(Activity activity) {
        ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0);
        if (rootView instanceof DrawerLayout) {
            return (DrawerLayout) rootView;
        }
        return null;
    }

    private static void setDrawerLayoutProperty(DrawerLayout drawerLayout) {
        ViewGroup drawer = (ViewGroup) drawerLayout.getChildAt(1);
        drawerLayout.setFitsSystemWindows(false);
        drawer.setFitsSystemWindows(false);
    }

    @TargetApi(Build.VERSION_CODES.M)
    public static void setLightMode(Activity activity) {
        setMIUIStatusBarDarkIcon(activity, true);
        setMeizuStatusBarDarkIcon(activity, true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    public static void setDarkMode(Activity activity) {
        setMIUIStatusBarDarkIcon(activity, false);
        setMeizuStatusBarDarkIcon(activity, false);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        }
    }

    private static void setRootView(Activity activity) {
        ViewGroup parent = activity.findViewById(android.R.id.content);
        for (int i = 0; i < parent.getChildCount(); i++) {
            View childView = parent.getChildAt(i);
            if (childView instanceof ViewGroup) {
                childView.setFitsSystemWindows(true);
                ((ViewGroup) childView).setClipToPadding(true);
            }
        }
    }

    private static View createStatusBarView(Activity activity, @ColorInt int color) {
        View statusBarView = new View(activity);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
        statusBarView.setLayoutParams(params);
        statusBarView.setBackgroundColor(color);
        statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
        return statusBarView;
    }

    private static int getStatusBarHeight(Context context) {
        // 獲得狀態(tài)欄高度
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        return context.getResources().getDimensionPixelSize(resourceId);
    }

    /**
     * 修改 MIUI V6  以上狀態(tài)欄顏色
     */
    private static void setMIUIStatusBarDarkIcon(@NonNull Activity activity, boolean darkIcon) {
        Class<? extends Window> clazz = activity.getWindow().getClass();
        try {
            Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
            Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
            int darkModeFlag = field.getInt(layoutParams);
            Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
            extraFlagField.invoke(activity.getWindow(), darkIcon ? darkModeFlag : 0, darkModeFlag);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 修改魅族狀態(tài)欄字體顏色 Flyme 4.0
     */
    private static void setMeizuStatusBarDarkIcon(@NonNull Activity activity, boolean darkIcon) {
        try {
            WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
            Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
            Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
            darkFlag.setAccessible(true);
            meizuFlags.setAccessible(true);
            int bit = darkFlag.getInt(null);
            int value = meizuFlags.getInt(lp);
            if (darkIcon) {
                value |= bit;
            } else {
                value &= ~bit;
            }
            meizuFlags.setInt(lp, value);
            activity.getWindow().setAttributes(lp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

為了在Fragment切換時(shí)修改同一Activity的狀態(tài)欄,所以我們得給偽狀態(tài)欄設(shè)置id(及在values目錄下新建一資源文件ids)

<item name="status_bar_util_fake_status_bar_view" type="id" />
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碌尔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子券敌,更是在濱河造成了極大的恐慌唾戚,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件待诅,死亡現(xiàn)場(chǎng)離奇詭異叹坦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)卑雁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門募书,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人测蹲,你說(shuō)我怎么就攤上這事莹捡。” “怎么了扣甲?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵篮赢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我琉挖,道長(zhǎng)启泣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任示辈,我火速辦了婚禮寥茫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘矾麻。我一直安慰自己纱耻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布险耀。 她就那樣靜靜地躺著膝迎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胰耗。 梳的紋絲不亂的頭發(fā)上限次,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼卖漫。 笑死费尽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼倘要,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼炬丸!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起及塘,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后缘缚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡敌蚜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年桥滨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弛车。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡齐媒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纷跛,到底是詐尸還是另有隱情喻括,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布贫奠,位于F島的核電站双妨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏叮阅。R本人自食惡果不足惜刁品,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浩姥。 院中可真熱鬧挑随,春花似錦、人聲如沸勒叠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)眯分。三九已至拌汇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弊决,已是汗流浹背噪舀。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工魁淳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人与倡。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓界逛,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親纺座。 傳聞我的和親對(duì)象是個(gè)殘疾皇子息拜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

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