preloader image
Android 设置状态栏颜色和状态栏文字、图标颜色

Android 设置状态栏颜色和状态栏文字、图标颜色

Android开发中,经常需要实现下图状态栏的效果,类似于沉浸式状态栏,但这里仅仅是讨论设置状态栏的颜色和状态栏上面文字、图标的颜色的方法。

Android 4.4(API 19)之后,就提供了修改状态栏颜色的方法,但是在 Android 6.0(API 23)之后,才支持修改状态栏上面的文字和图标颜色,默认是白色的。所以会导致一个问题,在 4.4 到 6.0 之间的系统,状态栏设置为浅色的话,状态栏上面白色的文字和图标会看不清,像下面这样:

有一些第三方的系统提供了设置状态栏和状态栏文字、图标颜色的方法,比如小米的MIUI和魅族的Flyme,所以考虑了下比较好的实现方式是:

Android 4.4 以上使用 SystemBarTint 修改状态栏颜色;Android 6.0 以上使用系统方法修改状态栏字体、图标颜色;Android 4.4 到 6.0 之间使用第三方系统提供的方法修改状态栏字体、图标颜色(目前只有 MIUI 和 Flyme)。

当然,这里面也会有坑,比如 MIUI 提供的修改状态栏字体颜色方法会跟 Android 系统自带的方法冲突,官方说明如下: 关于MIUI状态栏字符颜色逻辑调整说明

经过网上的资料和自己的尝试,MIUI 系统还是同时使用 MIUI 提供的方法和 Android 系统自带的方法来修改状态栏字体颜色比较保险。

基于上面的思考,封装了设置 Android 4.4 以上系统状态栏颜色和状态栏字体、图标颜色的方法:

首先,需要引入 SystemBarTint 库:

dependencies {

compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'

}

隐藏标题栏

要在 Application Theme 加上 true ,不然页面会顶到状态栏上面,或者在 Activity 的布局里面加上 android:fitsSystemWindows="true" 和 android:clipToPadding="false" 也可以。

状态栏工具类 StatusBarUtil.java

package com.jairus;

import android.annotation.TargetApi;

import android.app.Activity;

import android.graphics.Color;

import android.os.Build;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

import com.readystatesoftware.systembartint.SystemBarTintManager;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

/**

* 状态栏工具类

* 作者: JairusTse

* 日期: 17/12/19

*/

public class StatusBarUtil {

/**

* 设置状态栏为透明

* @param activity

*/

@TargetApi(19)

public static void setTranslucentStatus(Activity activity) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

Window window = activity.getWindow();

window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);

window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

window.setStatusBarColor(Color.TRANSPARENT);

} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

Window window = activity.getWindow();

window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,

WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

}

}

/**

* 修改状态栏颜色,支持4.4以上版本

* @param activity

* @param colorId

*/

public static void setStatusBarColor(Activity activity, int colorId) {

//Android6.0(API 23)以上,系统方法

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

Window window = activity.getWindow();

window.setStatusBarColor(activity.getResources().getColor(colorId));

} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

//使用SystemBarTint库使4.4版本状态栏变色,需要先将状态栏设置为透明

setTranslucentStatus(activity);

//设置状态栏颜色

SystemBarTintManager tintManager = new SystemBarTintManager(activity);

tintManager.setStatusBarTintEnabled(true);

tintManager.setStatusBarTintResource(colorId);

}

}

/**

* 设置状态栏模式

* @param activity

* @param isTextDark 文字、图标是否为黑色 (false为默认的白色)

* @param colorId 状态栏颜色

* @return

*/

public static void setStatusBarMode(Activity activity, boolean isTextDark, int colorId) {

if(!isTextDark) {

//文字、图标颜色不变,只修改状态栏颜色

setStatusBarColor(activity, colorId);

} else {

//修改状态栏颜色和文字图标颜色

setStatusBarColor(activity, colorId);

//4.4以上才可以改文字图标颜色

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

if(OSUtil.isMIUI()) {

//小米MIUI系统

setMIUIStatusBarTextMode(activity, isTextDark);

} else if(OSUtil.isFlyme()) {

//魅族flyme系统

setFlymeStatusBarTextMode(activity, isTextDark);

} else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

//6.0以上,调用系统方法

Window window = activity.getWindow();

window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

} else {

//4.4以上6.0以下的其他系统,暂时没有修改状态栏的文字图标颜色的方法,有可以加上

}

}

}

}

/**

* 设置Flyme系统状态栏的文字图标颜色

* @param activity

* @param isDark 状态栏文字及图标是否为深色

* @return

*/

public static boolean setFlymeStatusBarTextMode(Activity activity, boolean isDark) {

Window window = activity.getWindow();

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 (isDark) {

value |= bit;

} else {

value &= ~bit;

}

meizuFlags.setInt(lp, value);

window.setAttributes(lp);

result = true;

} catch (Exception e) {

}

}

return result;

}

/**

* 设置MIUI系统状态栏的文字图标颜色(MIUIV6以上)

* @param activity

* @param isDark 状态栏文字及图标是否为深色

* @return

*/

public static boolean setMIUIStatusBarTextMode(Activity activity, boolean isDark) {

boolean result = false;

Window window = activity.getWindow();

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 (isDark) {

extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体

} else {

extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体

}

result = true;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

//开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上

if (isDark) {

activity.getWindow().getDecorView().setSystemUiVisibility(View

.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View

.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

} else {

activity.getWindow().getDecorView().setSystemUiVisibility(View

.SYSTEM_UI_FLAG_VISIBLE);

}

}

} catch (Exception e) {

}

}

return result;

}

}

设备系统工具类 OSUtil.java

package com.jairus;

import android.os.Environment;

import android.text.TextUtils;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.util.Collection;

import java.util.Enumeration;

import java.util.Map;

import java.util.Properties;

import java.util.Set;

/**

* 设备系统工具类

* 作者: JairusTse

* 日期: 17/12/19

*/

public class OSUtil {

//MIUI标识

private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";

private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";

private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";

//EMUI标识

private static final String KEY_EMUI_VERSION_CODE = "ro.build.version.emui";

private static final String KEY_EMUI_API_LEVEL = "ro.build.hw_emui_api_level";

private static final String KEY_EMUI_CONFIG_HW_SYS_VERSION = "ro.confg.hw_systemversion";

//Flyme标识

private static final String KEY_FLYME_ID_FALG_KEY = "ro.build.display.id";

private static final String KEY_FLYME_ID_FALG_VALUE_KEYWORD = "Flyme";

private static final String KEY_FLYME_ICON_FALG = "persist.sys.use.flyme.icon";

private static final String KEY_FLYME_SETUP_FALG = "ro.meizu.setupwizard.flyme";

private static final String KEY_FLYME_PUBLISH_FALG = "ro.flyme.published";

/**

* 是否是Flyme系统

* @return

*/

public static boolean isFlyme() {

if(isPropertiesExist(KEY_FLYME_ICON_FALG, KEY_FLYME_SETUP_FALG, KEY_FLYME_PUBLISH_FALG)) {

return true;

}

try {

BuildProperties buildProperties = BuildProperties.newInstance();

if(buildProperties.containsKey(KEY_FLYME_ID_FALG_KEY)) {

String romName = buildProperties.getProperty(KEY_FLYME_ID_FALG_KEY);

if (!TextUtils.isEmpty(romName) && romName.contains(KEY_FLYME_ID_FALG_VALUE_KEYWORD)) {

return true;

}

}

} catch (IOException e) {

e.printStackTrace();

}

return false;

}

/**

* 是否是EMUI系统

* @return

*/

public static boolean isEMUI() {

return isPropertiesExist(KEY_EMUI_VERSION_CODE, KEY_EMUI_API_LEVEL,

KEY_EMUI_CONFIG_HW_SYS_VERSION);

}

/**

* 是否是MIUI系统

* @return

*/

public static boolean isMIUI() {

return isPropertiesExist(KEY_MIUI_VERSION_CODE, KEY_MIUI_VERSION_NAME,

KEY_MIUI_INTERNAL_STORAGE);

}

private static boolean isPropertiesExist(String... keys) {

if (keys == null || keys.length == 0) {

return false;

}

try {

BuildProperties properties = BuildProperties.newInstance();

for (String key : keys) {

String value = properties.getProperty(key);

if (value != null)

return true;

}

return false;

} catch (IOException e) {

return false;

}

}

private static final class BuildProperties {

private final Properties properties;

private BuildProperties() throws IOException {

properties = new Properties();

// 读取系统配置信息build.prop类

properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build" +

".prop")));

}

public boolean containsKey(final Object key) {

return properties.containsKey(key);

}

public boolean containsValue(final Object value) {

return properties.containsValue(value);

}

public Set> entrySet() {

return properties.entrySet();

}

public String getProperty(final String name) {

return properties.getProperty(name);

}

public String getProperty(final String name, final String defaultValue) {

return properties.getProperty(name, defaultValue);

}

public boolean isEmpty() {

return properties.isEmpty();

}

public Enumeration keys() {

return properties.keys();

}

public Set keySet() {

return properties.keySet();

}

public int size() {

return properties.size();

}

public Collection values() {

return properties.values();

}

public static BuildProperties newInstance() throws IOException {

return new BuildProperties();

}

}

}

在 Activity 里面调用:

//根据状态栏颜色来决定状态栏文字用黑色还是白色

StatusBarUtil.setStatusBarMode(this, true, R.color.c_ffffff);

最终实现的效果如下:

Copyright © 2088 暴雪游戏怀旧特刊 All Rights Reserved.
友情链接