Android状态栏白底黑字

作者: 卜俊文 | 来源:发表于2017-10-11 10:03 被阅读646次

    一、描述

    在项目中有的时候Ui设计状态栏背景颜色是白色的,虽然还挺好看,不过可坑了我们做程序的,需要对很多机型进行适配,此文章列举了兼容多个机型版本的状态栏方案。

    二、状态栏

    1 只要设置下面的代码即可,我是放在BaseActivtiy里面用的

    StatusBarUtil.transparencyBar(this); //设置状态栏全透明
    StatusBarUtil.StatusBarLightMode(this); //设置白底黑字
    

    2 状态栏兼容类,直接Copy即可

    public class StatusBarUtil {
    
        /**
         * 修改状态栏为全透明
         *
         * @param activity
         */
        @TargetApi(19)
        public static void transparencyBar(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以上版本MIUIV、Flyme和6.0以上版本其他Android
         *
         * @param activity
         * @return 1:MIUUI 2:Flyme 3:android6.0
         */
        public static int StatusBarLightMode(Activity activity) {
            int result = 0;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if (MIUISetStatusBarLightMode(activity, true)) {
                    //小米
                    result = 1;
                } else if (FlymeSetStatusBarLightMode(activity.getWindow(), true)) {
                    //魅族
                    result = 2;
                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    //6.0以上
                    activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                    result = 3;
                } else {
                    //其他的都设置状态栏成半透明的,以下设置半透明是调用第三方ImmersionBar库的,根据个人需求更改,
                    ImmersionBar.with(activity).statusBarDarkFont(true, 0.5f).init();
                }
            }
            return result;
        }
    
        /**
         * 设置状态栏图标为深色和魅族特定的文字风格
         * 可以用来判断是否为Flyme用户
         *
         * @param window 需要设置的窗口
         * @param dark   是否把状态栏文字及图标颜色设置为深色
         * @return boolean 成功执行返回true
         */
        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;
        }
    
        /**
         * 需要MIUIV6以上
         *
         * @param activity
         * @param dark     是否把状态栏文字及图标颜色设置为深色
         * @return boolean 成功执行返回true
         */
        public static boolean MIUISetStatusBarLightMode(Activity activity, boolean dark) {
            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 (dark) {
                        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 (dark) {
                            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;
        }
    }
    

    白底黑字

    半透明效果

    三、注意事项

    1 在适配中,有遇到一个 华为EMUI3.1 的手机设置上后有出现一些异常问题,我看有的第三方库也有对这个版本单独进行处理,应该是有点问题,所以我在项目中就直接屏蔽了这个版本的适配。

    四、相关资料

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

    ImmersionBar状态栏库

    五、总结

    此文章的工具类是从其他地方Copy来,精简了一些没有用到的代码,如果需要其他代码的,从第四点的链接进入查看就好,这类代码都是Copy来Copy去的,也找不到原创在哪了。。

    欢迎关注我的微信公众号,分享更多技术文章。

    相关文章

      网友评论

      • 孙小星:感谢,但是vivo手机还是白底白字,是因为 ImmersionBar.with(activity).statusBarDarkFont(true, 0.5f).init();这个注释了吗?
        卜俊文:@孙小星 是的,6.0以下的,就是我注释那行处理的。 现在就只有小米和魅族对这个状态栏发布了处理方案,其他的没有,所有解决方法只能设置状态栏为半透明了,不过现在大多数手机都有6.0了
        孙小星:@卜俊文 是的,6.0以下的vivo,oppo,都是这样,应该是那个注释的三方库原因
        卜俊文:你手机版本多少的6.0以下吗

      本文标题:Android状态栏白底黑字

      本文链接:https://www.haomeiwen.com/subject/mlmiyxtx.html