前言
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 库:
1 2 3
| dependencies { implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3' }
|
隐藏标题栏
1 2 3 4 5 6 7 8 9 10 11 12
| <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="android:fitsSystemWindows">true</item> </style>
|
要在 Application Theme 加上
1
| <item name="android:fitsSystemWindows">true</item>
|
不然页面会顶到状态栏上面,
或者
在 Activity 的布局里面加上
1 2
| android:fitsSystemWindows="true" android:clipToPadding="false"
|
也可以。
工具类
状态栏工具类 StatusBarUtil.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
| 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;
public class StatusBarUtil {
@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 ); } }
public static void setStatusBarColor(Activity activity, int colorId) { 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) { setTranslucentStatus(activity); SystemBarTintManager tintManager = new SystemBarTintManager(activity); tintManager.setStatusBarTintEnabled(true); tintManager.setStatusBarTintResource(colorId); } }
public static void setStatusBarMode(Activity activity, boolean isTextDark, int colorId) {
if(!isTextDark) { setStatusBarColor(activity, colorId); } else { setStatusBarColor(activity, colorId); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if(OSUtil.isMIUI()) { setMIUIStatusBarTextMode(activity, isTextDark); } else if(OSUtil.isFlyme()) { setFlymeStatusBarTextMode(activity, isTextDark); } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 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 { } } } }
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; }
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) { 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
| 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;
public class OSUtil { 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";
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";
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";
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; }
public static boolean isEMUI() { return isPropertiesExist(KEY_EMUI_VERSION_CODE, KEY_EMUI_API_LEVEL, KEY_EMUI_CONFIG_HW_SYS_VERSION); }
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(); 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<Map.Entry<Object, Object>> 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<Object> keys() { return properties.keys(); }
public Set<Object> keySet() { return properties.keySet(); }
public int size() { return properties.size(); }
public Collection<Object> values() { return properties.values(); }
public static BuildProperties newInstance() throws IOException { return new BuildProperties(); } } }
|
在 Activity 里面调用:
1 2
| StatusBarUtil.setStatusBarMode(this, true, R.color.color_f3);
|
最终实现的效果如下:

转载自:https://www.jianshu.com/p/3042bf7d72e3