Android 6.0 以上實(shí)現(xiàn)狀態(tài)欄白底黑字

Android 6.0 以上實(shí)現(xiàn)狀態(tài)欄白底黑字 「白色標(biāo)題欄 App 享受 iOS 般的沉浸體驗(yàn)」


前言: 其實(shí)我挺不愿意起這個(gè)標(biāo)題的,為什么 Android 非要做的跟 iOS 一樣, 但是對于狀態(tài)欄這個(gè)顏色這個(gè)需求我想還是有必要像 iOS 學(xué)習(xí)一下,畢竟 5.0 之前,狀態(tài)欄萬年黑色的樣子的確和大部分 App 的主題樣式有點(diǎn)不太融合, 但是最近受到產(chǎn)品的大哥在玩小密圈,看到他們的狀態(tài)欄效果,所以讓我也實(shí)現(xiàn)下也這樣的效果 O(∩_∩)O~。

網(wǎng)上關(guān)于「沉浸式狀態(tài)欄」「透明狀態(tài)欄」的文章 Google 一搜一大把。文章的開頭先給大家列舉一下幾個(gè)常見的實(shí)現(xiàn)方式吧:

  1. 如果你的 App 需要考慮 Android 4.4 版本的狀態(tài)欄顏色改變,那么就請移步這個(gè)第三方庫 SystemBarTint
  2. 如果你的 App 僅需要考慮 Android 5.0 版本以上的狀態(tài)欄顏色適配,這里推薦一個(gè)簡單實(shí)用的實(shí)現(xiàn)方式,薄荷TOOLBAR(ACTIONBAR)的適配方案

薄荷公司 statueBar 的適配方案

之前我們的 App 剛開始搭建的時(shí)候采用的是,薄荷公司的狀態(tài)欄適配方式,主要思路是:

  1. 設(shè)置主題狀態(tài)欄背景透明,在 values-v19 的文件夾下新建一個(gè) style 文件,

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
    </style>
    
  2. 設(shè)置并在該文件夾下添加 dimens 文件,設(shè)置 toolbar padding 為24dp

    <dimen name="toolbar_padding_top">24dp</dimen>
    
  3. 在 values 文件夾設(shè)置同名 dimens 的值為 0dp

    <dimen name="toolbar_padding_top">0dp</dimen>
    

    該屬性需要在你的 Toolbar 中設(shè)置一下 paddingTop 并引用該 dimens 值,這樣在不同版本的手機(jī)上,就會自動選擇不同的值。

  4. 并在app中的 baseActivity 類中實(shí)現(xiàn)如下代碼:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_base);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
            localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
        }
    }
    

    在代碼中實(shí)現(xiàn)上述代碼是因?yàn)閲鴥?nèi)有些 rom 如果單純在 style 文件中設(shè)置 windowTranslucentStatus 可能導(dǎo)致設(shè)置無效。所以在 Activity 中再次設(shè)置一遍 。

  5. 最后不要忘了在 清單文件中應(yīng)用你設(shè)置的主題。

上述為薄荷公司的實(shí)現(xiàn)方式如果有不明白的地方請看「stormzhang」的博客,薄荷TOOLBAR(ACTIONBAR)的適配方案


小米手機(jī),魅族手機(jī)狀態(tài)欄顏色適配

國內(nèi)某些知名手機(jī)品牌,對原生 rom 進(jìn)行深度優(yōu)化然后改造了屬于自己的 rom,但是這樣對開發(fā)者來說可能就是一定程度上的災(zāi)難,比如 小米和魅族 rom 已經(jīng)自己內(nèi)置修改狀態(tài)欄為白底透明的字體顏色為白色的,所以對于上述狀態(tài)欄適配的話:如果 app 的標(biāo)題欄是深色主題的還好,如果是淺色的如我們的 app 是白色的那么就會出現(xiàn),進(jìn)了我們 app 還想看時(shí)間,哈哈做夢吧。幸運(yùn)的是小米和魅族都給了對應(yīng)的解決方案,通過解決方案可以修改 app 內(nèi)部的狀態(tài)欄可以設(shè)置為黑色字體:

public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
        boolean result = false;
        if (window != null) {
            Class clazz = window.getClass();
            try {
                int darkModeFlag = 0;
                Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
                Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
                darkModeFlag = field.getInt(layoutParams);
                Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
                if (dark) {
                    extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//狀態(tài)欄透明且黑色字體
                } else {
                    extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字體
                }
                result = true;
            } catch (Exception e) {

            }
        }
        return result;
    }

對應(yīng)魅族的修改方法是:

 public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
        boolean result = false;
        if (window != null) {
            try {
                WindowManager.LayoutParams lp = window.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 (dark) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                window.setAttributes(lp);
                result = true;
            } catch (Exception e) {

            }
        }
        return result;
    }

最后我們需要在我們的BaseActivity 中加入適配代碼:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_base);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
            localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
        }
        
        MIUISetStatusBarLightMode(this.getWindow(), true);
        FlymeSetStatusBarLightMode(this.getWindow(), true);
    }

小米上實(shí)現(xiàn)效果:

看起來還不錯(cuò),但是之后看到在華為手機(jī) 5.0 以上的效果是這樣的:

這個(gè)可能就是各個(gè)rom優(yōu)化完以后的效果,作為一個(gè)精益求精的開發(fā)者,我認(rèn)為華為上這個(gè)效果實(shí)在是太丑了。那么有沒有更好的實(shí)現(xiàn)方案呢?

期間試了網(wǎng)上各種5.0 以上的狀態(tài)欄適配效果,在華為手機(jī)上都不太理想,大家都知道 Android 6.0 系統(tǒng)已經(jīng)發(fā)布近兩年時(shí)間了,國內(nèi)各個(gè)應(yīng)用廠商,也開始適配新的機(jī)型,所以我們考慮的是,為了達(dá)到不同手機(jī)上效果一致,所以就不采用任何第三方的方案了:『利用系統(tǒng)自帶的api,實(shí)現(xiàn) Android 6.0 以上的狀態(tài)欄適配』


利用系統(tǒng)自帶的api,實(shí)現(xiàn) Android 6.0 以上的狀態(tài)欄適配

因?yàn)橹安捎昧吮『晒镜倪m配方法,要修改的話就需要在最好的改動的情況下進(jìn)行修改:

  1. 修改 dimens 文件夾的 <dimen name="toolbar_padding_top">0dp</dimen> 均為 0dp;

  2. 修改主題樣式 將values-v19 修改為 values-v23 并且在styles 文件中就修改主題為:

        <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <item name="android:colorPrimaryDark">@color/title_color</item>
            <item name="android:colorPrimary">@color/white</item>
            <item name="android:colorAccent">@color/white</item>
            <item name="windowNoTitle">true</item>
        </style>
    
  3. 修改 BaseActivity 中的為:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 系統(tǒng) 6.0 以上 狀態(tài)欄白底黑字的實(shí)現(xiàn)方法
        this.getWindow()
            .getDecorView()
            .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        
        MIUISetStatusBarLightMode(this.getWindow(), true);
        FlymeSetStatusBarLightMode(this.getWindow(), true);
    }
    

運(yùn)行一下看下在華為手機(jī)上的效果:

Perfect! 這個(gè)效果老板和UI都很滿意,問題也圓滿解決了,我怕其他機(jī)型會有意外于是跑遍了公司所有的測試機(jī)和同事手機(jī)效果都一致,所以還算可以吧。


總結(jié)

個(gè)人認(rèn)為,谷歌官方不推薦做的如果你非要做,要么就需要踩很多坑,要么最終實(shí)現(xiàn)了效果也不是很理想,所以如果你的 app ,是像我們一樣的白色狀態(tài)欄的主題,那么就可以試一試我們這個(gè)方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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