Android狀態(tài)欄-字體顏色改變

識(shí)別MIUI和FLyme系統(tǒng)

目前只看到了小米和魅族公開了各自的實(shí)現(xiàn)方法牲尺,支持底層Android4.4以上的版本。而Android官方在6.0版本才有了深色狀態(tài)欄字體API直撤。所以Android4.4以上系統(tǒng)版本可以修改狀態(tài)欄顏色见坑,但是只有小米的MIUI、魅族的Flyme和Android6.0以上系統(tǒng)可以把狀態(tài)欄文字和圖標(biāo)換成深色地粪。

我們首先要了解如何識(shí)別手機(jī)系統(tǒng)。
這篇文章告訴我們如何判斷手機(jī)系統(tǒng)

整理出判斷MIUI琐谤,F(xiàn)Lyme系統(tǒng)的方法為

public class OSUtils {
    public static final String ROM_MIUI = "MIUI";
    public static final String ROM_FLYME = "FLYME";
    private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name";

    private static String sName;
    private static String sVersion;

    public static boolean isMiui() {
        return check(ROM_MIUI);
    }

    public static boolean isFlyme() {
        return check(ROM_FLYME);
    }

    public static boolean check(String rom) {
        if (sName != null) {
            return sName.equals(rom);
        }
        if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_MIUI))) {
            sName = ROM_MIUI;
        } else {
            sVersion = Build.DISPLAY;
            if (sVersion.toUpperCase().contains(ROM_FLYME)) {
                sName = ROM_FLYME;
            } else {
                sVersion = Build.UNKNOWN;
                sName = Build.MANUFACTURER.toUpperCase();
            }
        }
        return sName.equals(rom);
    }

    public static String getProp(String name) {
        String line = null;
        BufferedReader input = null;
        try {
            Process p = Runtime.getRuntime().exec("getprop " + name);
            input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
            line = input.readLine();
            input.close();
        } catch (IOException ex) {
            Log.e(TAG, "Unable to read prop " + name, ex);
            return null;
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return line;
    }
}

設(shè)置狀態(tài)欄透明

綜合上一篇文章蟆技,我們知道Android4.4.+ ,API 19 以上可以設(shè)置狀態(tài)欄透明,且 4.4 和 5.0 方式不同

  /**
     * 設(shè)置狀態(tài)欄透明
     */
    private void setTranslucentStatus() {

        // 5.0以上系統(tǒng)狀態(tài)欄透明
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            //清除透明狀態(tài)欄
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            //設(shè)置狀態(tài)欄顏色必須添加
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);//設(shè)置透明
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //19
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

我們?cè)O(shè)置的主題為NoActionBar斗忌,除此之外沒添加別的元素质礼。
這里我給button添加了顏色,可以看到button頂?shù)搅藸顟B(tài)欄织阳。


image

添加狀態(tài)欄高度

  public int getStatusBarHeight() {
        int statusBarHeight = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }

魅族字體設(shè)置方式

 public void setFlymeUI(boolean dark) {
        try {
            Window window = getWindow();
            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);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

小米字體設(shè)置方式

public void setMiuiUI(boolean dark) {
        try {
            Window window = getWindow();
            Class clazz = getWindow().getClass();
            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);
            if (dark) {    //黑色字體
                extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
            } else {       
                extraFlagField.invoke(window, 0, darkModeFlag);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Android 6.0 以上設(shè)置方式

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    getWindow().getDecorView().setSystemUiVisibility(
                            View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                                    | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

                }

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

這里介紹實(shí)現(xiàn)方式的一種眶蕉,通過自定義基類的Activity,讓所有要實(shí)現(xiàn)的Activity繼承它唧躲。

我們的基類布局設(shè)置的方式為:狀態(tài)欄+內(nèi)容實(shí)現(xiàn)布局造挽。
因此在實(shí)現(xiàn)過程中我們要將子類布局添加到我們的內(nèi)容實(shí)現(xiàn)布局中,還要將狀態(tài)欄設(shè)置為透明惊窖。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <View
        android:id="@+id/view_status_bar_place"
        android:layout_width="match_parent"
        android:layout_height="25dp"/>

    <FrameLayout
        android:id="@+id/frame_layout_content_place"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

總的實(shí)現(xiàn)方法為刽宪,下面是全部代碼(要耐心看)

import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by rhm on 2018/1/12.
 */

public class CompactActivity extends AppCompatActivity {
    private FrameLayout mFrameLayoutContent;
    private View mViewStatusBarPlace;
    private final static int MIUI = 0;
    private final static int FLYME = 1;
    private final static int COMMON = 2;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_status_bar);
        mViewStatusBarPlace = findViewById(R.id.view_status_bar_place);
        mFrameLayoutContent = (FrameLayout) findViewById(R.id.frame_layout_content_place);

        ViewGroup.LayoutParams params = mViewStatusBarPlace.getLayoutParams();
        params.height = getStatusBarHeight();
        mViewStatusBarPlace.setLayoutParams(params);
    }

//將子類布局添加到FrameLayout中
    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        View contentView = LayoutInflater.from(this).inflate(layoutResID, null);
        mFrameLayoutContent.addView(contentView);
    }


    /**
     * 設(shè)置沉浸式狀態(tài)欄
     *
     * @param fontIconDark 狀態(tài)欄字體和圖標(biāo)顏色是否為深色
     */
    protected void setImmersiveStatusBar(boolean fontIconDark) {
        setTranslucentStatus();
        if (fontIconDark) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                setStatusBarFontIconDark(COMMON);
            } else if (OSUtils.isMiui()) {
                setStatusBarFontIconDark(MIUI);
            } else if (OSUtils.isFlyme()) {
                setStatusBarFontIconDark(FLYME);
            } else {//其他情況下我們將狀態(tài)欄設(shè)置為灰色厘贼,就不會(huì)看不見字體
                setStatusBarPlaceColor(Color.LTGRAY);//灰色
            }
        }
    }

    /**
     * 設(shè)置文字顏色
     */
    public void setStatusBarFontIconDark(int type) {
        switch (type) {
            case MIUI:
                setMiuiUI(true);
                break;
            case COMMON:
                setCommonUI();
                break;
            case FLYME:
                setFlymeUI(true);
                break;
        }
    }

    public void setCommonUI() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            getWindow().getDecorView().setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

        }
    }

    public void setFlymeUI(boolean dark) {
        try {
            Window window = getWindow();
            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);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setMiuiUI(boolean dark) {
        try {
            Window window = getWindow();
            Class clazz = getWindow().getClass();
            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);
            if (dark) {    //狀態(tài)欄亮色且黑色字體
                extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
            } else {
                extraFlagField.invoke(window, 0, darkModeFlag);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setStatusBarPlaceColor(int statusColor) {
        if (mViewStatusBarPlace != null) {
            mViewStatusBarPlace.setBackgroundColor(statusColor);
        }
    }

    /**
     * 設(shè)置狀態(tài)欄透明
     */
    private void setTranslucentStatus() {

        // 5.0以上系統(tǒng)狀態(tài)欄透明
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            //清除透明狀態(tài)欄
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            //設(shè)置狀態(tài)欄顏色必須添加
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);//設(shè)置透明
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //19
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    //設(shè)置狀態(tài)欄高度
    public int getStatusBarHeight() {
        int statusBarHeight = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }
}

狀態(tài)欄默認(rèn)為主題顏色界酒。可以根據(jù)需要設(shè)置狀態(tài)欄的顏色嘴秸,字體是否顯示為黑色毁欣。
實(shí)現(xiàn)代碼為:

public class MainActivity extends CompactActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setImmersiveStatusBar(true);
        }
        }
image

下一篇庇谆,我會(huì)介紹另一種實(shí)現(xiàn)方式。

參考文章
http://www.reibang.com/p/a44c119d6ef7
http://yifeng.studio/2017/02/19/android-statusbar/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凭疮,一起剝皮案震驚了整個(gè)濱河市饭耳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌执解,老刑警劉巖寞肖,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異衰腌,居然都是意外死亡新蟆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門右蕊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琼稻,“玉大人,你說我怎么就攤上這事饶囚∨练” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵萝风,是天一觀的道長嘀掸。 經(jīng)常有香客問我,道長闹丐,這世上最難降的妖魔是什么横殴? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮卿拴,結(jié)果婚禮上衫仑,老公的妹妹穿的比我還像新娘。我一直安慰自己堕花,他們只是感情好文狱,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缘挽,像睡著了一般瞄崇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上壕曼,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天苏研,我揣著相機(jī)與錄音,去河邊找鬼腮郊。 笑死摹蘑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的轧飞。 我是一名探鬼主播衅鹿,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼撒踪,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了大渤?” 一聲冷哼從身側(cè)響起制妄,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泵三,沒想到半個(gè)月后耕捞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烫幕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年砸脊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纬霞。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凌埂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诗芜,到底是詐尸還是另有隱情瞳抓,我是刑警寧澤,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布伏恐,位于F島的核電站孩哑,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏翠桦。R本人自食惡果不足惜横蜒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望销凑。 院中可真熱鬧丛晌,春花似錦、人聲如沸斗幼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜕窿。三九已至谋逻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間桐经,已是汗流浹背毁兆。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阴挣,地道東北人气堕。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親送巡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

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