我尽量不打错别字,用词准确,不造成阅读障碍。

昨天在OPPO开发者后台清理未读消息时看到一篇介绍状态栏反色(白底黑字)的文章,心血来潮看了一下,然后就查阅了国内各个ROM的不同处理方式,写一篇小总结,希望能帮助到需要的人。

前言

Android6.0(M)以后,Google给出了官方修改状态栏白底黑字的方式 ,各大厂商基本都适用,所以应该不用适配 (“应该”是因为我没有那么多手机,没法逐个确认),在6.0之前的系统,国内不同厂家有的提供了实现方法,有的没有。比如我查阅到的几家,MIUI6开始提供了方法,OPPO的Color3.0开始且Android5.1提供了方法,魅族Flyme4.0提供了方法,华为开发者文档里没查到,vivo开发者文档里没查到,论坛里有说是Android5.0以后才提供沉浸式状态栏设置,其他手机没查了比如三星、索尼什么的(其实是因为没有测试机)。

注意:个人觉得状态栏基本有三个修改点:1.透明,全屏 ;2.改背景颜色与主题适配(感觉和上一个差不多);3.白底黑字或黑底白字;这三个修改点Google给出的官方方法时间不一样,前两个5.0就可以了,如果是4.4,网上也有很多实现的方法和思路,最后一个官方在6.0以后才给出方法,所以项目中写状态栏工具的时候还是要考虑很多东西的。

我手里的测试机有

华为荣耀6P:Android6.0 & EMUI4.0.1;//由于华为手机没有文档,所以还是很有测试价值的

红米R3s:Android6.0 & MIUI9; //MIUI6实在找不到,那得什么年代的机子了?

OPPOR9m:Android5.1 & Color3.0; //6.0以下的只有这一部

小米8:Android8.1.0 & MIUI10.0;

各种模拟器;

虽然设备条件不足,但是还是有一些可取之处的,所以只希望能提供一些帮助。

一.Android6.0及以上

效果四连:

主要就是改成黑色字体,背景其实好改很多。

代码如下:

public static void setStatusColor(Activity activity, boolean isTranslate, boolean isDarkText, @ColorRes int bgColor) {//如果系统为6.0及以上,就可以使用Android自带的方式if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {Window window = activity.getWindow();View decorView = window.getDecorView();window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); //可有可无decorView.setSystemUiVisibility((isTranslate ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : 0) | (isDarkText ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0));window.setStatusBarColor(isTranslate ? Color.TRANSPARENT : ContextCompat.getColor(activity, bgColor)); //Android5.0就可以用} }

在setSystemUiVisibility里面设置就可以分别实现全屏和文字黑色;

二.Android6.0以下

MIUI6以上

小米文档写的是MIUI全面支持原生写法,MIUI中Android6.0及以上用原生的,MIUI6以上Android6.0以下用MIUI自己的,所以你得写两套。首先要判断是否是MIUI6以后的版本:

private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name";
private static boolean isMIUI6Later() {try {Class<?> cla = Class.forName("android.os.SystemProperties");Method mtd = cla.getMethod("get", String.class);String val = (String) mtd.invoke(null, KEY_VERSION_MIUI);val = val.replaceAll("[vV]", "");int version = Integer.parseInt(val);return version >= 6;} catch (Exception e) {e.printStackTrace();return false;}
}

网上还有一种获取厂商自定义系统的方法,具体忘记了,那个方法很耗时,几百毫秒左右,使用反射一般就1~2毫秒。

根据官方文档,设置透明和设置状态栏反色是两个步骤:

//设置透明
private static void setMIUI6Translate(Activity activity, boolean on) {Window win = activity.getWindow();WindowManager.LayoutParams winParams = win.getAttributes();final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;if (on) {winParams.flags |= bits;} else {winParams.flags &= ~bits;}win.setAttributes(winParams);}//设置黑色字符private static void setMIUI6StatusBarDarkMode(Activity activity, boolean darkmode) {Class<? extends Window> clazz = activity.getWindow().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);extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag);} catch (Exception e) {e.printStackTrace();}}

由于我没有MIUI6以上&Android6.0以下的手机,所以没有测试,但是这是官方文档给的方法,应该是有保证的。

链接:https://dev.mi.com/console/doc/detail?pId=1159

官方还给了实现白色字符的方式:

int flag =window.getDecorView().getSystemUiVisibility()&~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
window.getDecorView().setSystemUiVisibility(flag);
OPPOColor3.0

官方只给了Color3.0&Android5.1的情况,其它的也没说不行或行,是不是Color3.0以上Android6.0以下只有这一种机器?先判断系统是不是Color3.0以上的,与判断MIUI6的方法一样:

private static final String KEY_VERSION_OPPO = "ro.build.version.opporom";
private static boolean isColorOS_3() {try {Class<?> cla = Class.forName("android.os.SystemProperties");Method mtd = cla.getMethod("get", String.class);String val = (String) mtd.invoke(null, KEY_VERSION_OPPO);val = val.replaceAll("[vV]", "");val = val.substring(0, 1);int version = Integer.parseInt(val);return version >= 3;} catch (Exception e) {e.printStackTrace();return false;}}

设置字体颜色:

private void setOppoStausBar(){//控制字体颜色,只有黑白两色int SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT = isDarkText ? 0x00000010 : 0x00190000;Window window = activity.getWindow();View decorView = window.getDecorView();decorView.setSystemUiVisibility((isTranslate ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : 0) | SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT);window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); //可有可无window.setStatusBarColor(isTranslate ? Color.TRANSPARENT : ContextCompat.getColor(activity, bgColor));
}

可以看出来,OPPO的修改与Android6.0以上的修改唯一不同的就是setSystemUiVisibility中设置字符颜色的标识是自己手写的,不是使用系统的,官方给的是0x00000010,这个数值我随便输了几个,发现只有黑白两色。
开发者链接:https://open.oppomobile.com/wiki/doc#id=10161

Flyme4.0

魅族我没有机子,都是在官方的基础上归纳的:判断是否为Flyme4.0:

private static boolean isFlyme4Later() {if ("MEIZU".equals(Build.BRAND.trim().toUpperCase())) {return Build.FINGERPRINT.contains("Flyme_OS_4") || Build.VERSION.INCREMENTAL.contains("Flyme_OS_4") || Pattern.compile("Flyme_OS_[4|5]", Pattern.CASE_INSENSITIVE).matcher(Build.DISPLAY).find();}return false;
}

郑重说明,我没有机子,这个方法是网上找的,我本来一位可以使用判断小米和OPPO一样的方法,但是不行,没找到KEY_VERSION,没有机子也测不了。

设置字体颜色:

 private static void darModeForFlyme4(Activity activity, boolean dark) {boolean result = false;try {WindowManager.LayoutParams e = 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(e);if (dark) {value |= bit;} else {value &= ~bit;}meizuFlags.setInt(e, value);activity.getWindow().setAttributes(e);} catch (Exception var8) {Log.e("StatusBar", "darkIcon: failed");}}

以上是个整合版本,官方给了一个工具类,链接:http://open-wiki.flyme.cn/doc-wiki/index#id?79

吐槽一句,魅族真麻烦,周围连个测试机都没有。

其他

包括没找到文档的华为、VIVO,没找文档的三星、索尼、诺基亚、锤子、360等

设置全屏透明及背景色:

public static void setStatusTranslate(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {View decorView = activity.getWindow().getDecorView();decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);activity.getWindow().setStatusBarColor(Color.TRANSPARENT);} else {//感觉5.0以下(4.4及以下)可以放弃了activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}
}public static void setStatusBarColor(Activity activity, int color) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().setStatusBarColor(activity.getResources().getColor(color));}
}

因为没有文档,所以没有找到设置状态栏反色的方法,如果是Android6.0及以上,以上品牌应该是都可以使用原生方法的。

本文旨在提供一些帮助,因为测试机有限,所以可能帮助的不多,你也可以再次基础上进行添加等修改,以符合项目要求。完整代码如下:

public class StatusBarUtil {private static final String KEY_VERSION_OPPO = "ro.build.version.opporom";    //OPPOprivate static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name";     //小米private static final String KEY_VERSION_EMUI = "ro.build.version.emui";       //华为private static final String KEY_VERSION_SMARTISAN = "ro.smartisan.version";   //锤子private static final String KEY_VERSION_VIVO = "ro.vivo.os.version";          //vivo/*** 设置状态栏透明度、背景颜色、文字颜色* @param isTranslate 是否透明,若为true,则bgColor设置无效* @param isDarkText  字体颜色,只有黑白两色,无论什么色值,都只会转为黑白两色* @param bgColor     背景色,即状态栏颜色,isTranslate若为true则此值无效*/public static void setStatusColor(Activity activity, boolean isTranslate, boolean isDarkText, @ColorRes int bgColor) {//如果系统为6.0及以上,就可以使用Google自带的方式if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {Window window = activity.getWindow();View decorView = window.getDecorView();//可有可无window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);   decorView.setSystemUiVisibility((isTranslate ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : 0) | (isDarkText ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0));window.setStatusBarColor(isTranslate ? Color.TRANSPARENT : ContextCompat.getColor(activity, bgColor));} else { //如果不是6.0及以上则分情况适配if (isColorOS_3()) { //如果是OPPO Color3.0 & Android 5.1//控制字体颜色,只有黑白两色final int SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT = isDarkText ? 0x00000010 : 0x00190000;  Window window = activity.getWindow();View decorView = window.getDecorView();decorView.setSystemUiVisibility((isTranslate ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : 0) | SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT);//可有可无window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setStatusBarColor(isTranslate ? Color.TRANSPARENT : ContextCompat.getColor(activity, bgColor));} else if (isMIUI6Later()) { //如果是Android 6.0以下,MIUI6及以上setMIUI6Translate(activity, isTranslate);setMIUI6StatusBarDarkMode(activity, isDarkText);} else if (isFlyme4Later()) {darModeForFlyme4(activity, isDarkText);if (isTranslate) {setStatusTranslate(activity);}} else {//既不属于MIUI6,也不属于OPPO,还不属于魅族,极有可能是华为、三星、索尼、诺基亚、VIVO、锤子、360等if (isTranslate) {setStatusTranslate(activity);}setStatusBarColor(activity, isTranslate ? Color.TRANSPARENT : ContextCompat.getColor(activity, bgColor));}}}/*** 是否是MIUI6及以后版本* @return 是否是MIUI6*/private static boolean isMIUI6Later() {try {Class<?> cla = Class.forName("android.os.SystemProperties");Method mtd = cla.getMethod("get", String.class);String val = (String) mtd.invoke(null, KEY_VERSION_MIUI);val = val.replaceAll("[vV]", "");int version = Integer.parseInt(val);return version >= 6;} catch (Exception e) {e.printStackTrace();return false;}}/*** 设置MIUI6及以上状态栏透明,字体为默认白色,Android6.0以上也可以* @param on 是否为透明*/private static void setMIUI6Translate(Activity activity, boolean on) {Window win = activity.getWindow();WindowManager.LayoutParams winParams = win.getAttributes();final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;if (on) {winParams.flags |= bits;} else {winParams.flags &= ~bits;}win.setAttributes(winParams);}/*** 设置MIUI6及以上,Android6.0以下版本状态栏黑色字符* Android 6.0以上此方法无效* 此方法是官方给的,应该没有错,我没有MIUI6的手机,无法测试*/private static void setMIUI6StatusBarDarkMode(Activity activity, boolean darkmode) {Class<? extends Window> clazz = activity.getWindow().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);extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag);} catch (Exception e) {e.printStackTrace();}}/*** 是否是ColorOS_3.0系统 Android 5.1* @return 是否是colorOS_3.0*/private static boolean isColorOS_3() {try {Class<?> cla = Class.forName("android.os.SystemProperties");Method mtd = cla.getMethod("get", String.class);String val = (String) mtd.invoke(null, KEY_VERSION_OPPO);val = val.replaceAll("[vV]", "");val = val.substring(0, 1);int version = Integer.parseInt(val);return version >= 3;} catch (Exception e) {e.printStackTrace();return false;}}/*** 判断是否是魅族Flyme4* @return 是否是魅族Flyme4*/private static boolean isFlyme4Later() {if ("MEIZU".equals(Build.BRAND.trim().toUpperCase())) {return Build.FINGERPRINT.contains("Flyme_OS_4") || Build.VERSION.INCREMENTAL.contains("Flyme_OS_4") || Pattern.compile("Flyme_OS_[4|5]", Pattern.CASE_INSENSITIVE).matcher(Build.DISPLAY).find();}return false;}/*** 设置魅族Flyme4以后 状态栏黑色字体* 没有手机,从网上找的方法,应该没问题* @param dark 是否黑色*/private static void darModeForFlyme4(Activity activity, boolean dark) {boolean result = false;try {WindowManager.LayoutParams e = 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(e);if (dark) {value |= bit;} else {value &= ~bit;}meizuFlags.setInt(e, value);activity.getWindow().setAttributes(e);} catch (Exception var8) {Log.e("StatusBar", "darkIcon: failed");}}/*** 设置状态栏透明,Android4.4、Android5.0以上方法不一* 我感觉5.0以下的系统已经很少了吧,应该不需要适配了吧* 如果只是设置状态栏透明,就使用这个就好了*/public static void setStatusTranslate(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {View decorView = activity.getWindow().getDecorView();decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);activity.getWindow().setStatusBarColor(Color.TRANSPARENT);} else {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}}/*** 设置状态栏背景颜色,不适配5.0以下系统* @param color 颜色值*/public static void setStatusBarColor(Activity activity, int color) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().setStatusBarColor(activity.getResources().getColor(color));}}
}

关于Android状态栏反色(白底黑字)的适配小总结相关推荐

  1. Android设置状态栏为白底黑字

    在开发过程中可能会有将状态栏设置成白底黑字的样式,但是Android系统只有在4.4之上才可以修改状态栏颜色,想要设置状态栏为黑字,只有在Android6.0以上系统或者小米的MIUI V6以上版本或 ...

  2. Android设置白底黑字状态栏(已适配Flyme和新旧版MIUI)

    Android默认深主题色白字状态栏,这跟浅色的界面实在是不搭,那就改成黑字,底色随便改. 在Android6.0以前,这事不好办,所以MIUI自己实现了一个方法供开发者使用,Flyme也有(不知道是 ...

  3. android白色字体代码,Android实现状态栏白底黑字效果示例代码

    前言 本文主要给大家介绍了关于Android如何实现状态栏白底黑字的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.描述 在项目中有的时候Ui设计状态栏背景颜色是白色的 ...

  4. 白底黑子android菜单栏,白底黑字状态栏(详细使用步骤及各机型测试结果)

    前言 我个人比较喜欢黑白搭的风格,显得简约.文艺. 说到Android白底黑字状态栏.都会看到过这篇文章白底黑字!Android浅色状态栏黑色字体模式,这也是我最喜欢的一篇文章.(感觉是技术与美貌并存 ...

  5. 白底黑字!Android浅色状态栏黑色字体模式

    公司项目UI改版的时候,把大部分标题栏都设计成了白色,给我们的设计图是这个样子的: 设计图.png 这状态栏布局和图标挺像Android,但是这白底黑字Android设计规范里可没有啊,于是我们开发的 ...

  6. PDF反色处理/暗色模式保存,白底黑字转黑底白字

    使用BookxNote时,发现一个很人性化的功能:暗色模式: 既能够自动将白底黑字的pdf文件进行反色处理,类似于图片处理中的反相. 但这个功能仅仅是一个显示的功能,也就是没有对文件本身的色彩进行修改 ...

  7. android状态栏白色,Android如何实现状态栏白底黑字效果

    Android如何实现状态栏白底黑字效果 发布时间:2021-04-16 12:28:10 来源:亿速云 阅读:77 作者:小新 这篇文章给大家分享的是有关Android如何实现状态栏白底黑字效果的内 ...

  8. Android StatusBar 状态栏白底黑字设置

    项目中的一个场景UI要求使用白底黑字,并且白底要与大背景的颜色保持一致.需求很简单,可能我们的第一反应就是沉浸式或全屏模式,但这个场景中的某些操作又使得不能使用沉浸式或全屏模式.所以,我们必须用其他方 ...

  9. matlab 画图 白底黑字,白底黑字状态栏(详细使用步骤及各机型测试结果)

    前言 我个人比较喜欢黑白搭的风格,显得简约.文艺. 说到Android白底黑字状态栏.都会看到过这篇文章白底黑字!Android浅色状态栏黑色字体模式,这也是我最喜欢的一篇文章.(感觉是技术与美貌并存 ...

最新文章

  1. 7、ReadWriteLock
  2. 故障码123401_电力系统规划设计对电力工程设计的应用
  3. HQ-day2 C#语言基础
  4. 复练-软考高级-论文写作专题
  5. [Java面经] 关于面试的二三事.
  6. 2019最受欢迎数据库:MySQL居首PostgreSQL第二Oracle位列第八
  7. mysql分頁查詢_mysql分頁查詢 | 學步園
  8. Shiro的多Realm验证的实现--shiro实现不同身份使用不同Realm进行验证
  9. 2月14 大数据处理的基本算法
  10. 算法之 --- 背包01版+ 挖金矿问题
  11. 零代码组态搭建的水泥生产工艺流程
  12. 射雕英雄传人物关系python_《射雕英雄传》人物关系图
  13. 【漏洞复现】MS17-010漏洞(永恒之蓝)复现
  14. 单片机c语言 软件抗干扰,单片机软件抗干扰的几种常见方法
  15. 小陷胸汤加味方与乳汁淤积
  16. matlab相机标定Options选项解析
  17. 2020 年山东省职业院校技能大赛 (中职组)网络搭建与应用竞赛
  18. 雕刻机主轴正确的选型指引
  19. 素描史上最全手、脚画法丨必须收藏…
  20. Java程序员从笨鸟到菜鸟之——总结和声明

热门文章

  1. 如何利用动态代理IP来做SEO(网络营销)
  2. 详解java集合框架
  3. 青海黑枸杞形象塑造之路看地理标志产品柴达木枸杞品牌形象推广思路
  4. 9,共模抑制比一-不受输入信号中共模波动的影响。【如何分析共模CM抑制比。】
  5. [Vue]点击事件获取元素本身及事件
  6. 【开源项目】X-TRACK源码分析
  7. Merkle Tree 简介
  8. C语言规定 定义符号常量时必须用大写字母,C语言规定,定义符号常量时必须用大写字母()...
  9. 中国纹身针市场趋势报告、技术动态创新及市场预测
  10. spring-boot自定义yml读取