美文网首页Android开发Android开发Android技术知识
白底黑字状态栏(详细使用步骤及各机型测试结果)

白底黑字状态栏(详细使用步骤及各机型测试结果)

作者: Vincent7Wong | 来源:发表于2018-08-09 17:45 被阅读136次

    前言

    我个人比较喜欢黑白搭的风格,显得简约、文艺。

    说到Android白底黑字状态栏、都会看到过这篇文章白底黑字!Android浅色状态栏黑色字体模式,这也是我最喜欢的一篇文章、(感觉是技术与美貌并存哈哈哈),拿过来调用、变色了、ok了,但之后总会有部分机型出现问题、有时候一气之下就放弃了这个设计、回到原来的灰色状态栏。

    每次都心有不甘,这次决定花点时间研究一下...

    使用

    /**
    * Created by 赵晨璞 
    */
    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以上版本
     * @param activity
     * @param colorId
     */
    public static void setStatusBarColor(Activity activity,int colorId) {
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
    //      window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);  
            window.setStatusBarColor(activity.getResources().getColor(colorId));
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //使用SystemBarTint库使4.4版本状态栏变色,需要先将状态栏设置为透明
            transparencyBar(activity);
            SystemBarTintManager tintManager = new SystemBarTintManager(activity);
            tintManager.setStatusBarTintEnabled(true);
            tintManager.setStatusBarTintResource(colorId);
        }
    }
    
    /**
     *状态栏亮色模式,设置状态栏黑色文字、图标,
     * 适配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) {
                activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                result=3;
            }
        }
        return result;
    }
    
    /**
     * 已知系统类型时,设置状态栏黑色文字、图标。
     * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
     * @param activity
     * @param type 1:MIUUI 2:Flyme 3:android6.0
     */
    public static void StatusBarLightMode(Activity activity,int type){
        if(type==1){
           MIUISetStatusBarLightMode(activity, true);
        }else if(type==2){
            FlymeSetStatusBarLightMode(activity.getWindow(), true);
        }else if(type==3){
            activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }
    
    }
    
    /**
     * 状态栏暗色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标
     */
    public static void StatusBarDarkMode(Activity activity,int type){
        if(type==1){
            MIUISetStatusBarLightMode(activity, false);
        }else if(type==2){
            FlymeSetStatusBarLightMode(activity.getWindow(), false);
        }else if(type==3){
            activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
        }
    
    }
    
    
    /**
     * 设置状态栏图标为深色和魅族特定的文字风格
     * 可以用来判断是否为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;
    }
    }
    

    将代码复制后SystemBarTintManager报红,需要依赖(为了兼容Android4.4)

      implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3'
    

    Activity中传入状态栏需要改变的颜色

     StatusBarUtil.StatusBarLightMode(this,R.color.white);
    

    这里需要注意的是、设置状态栏透明后、Activity布局会上移(Android4.4以上)


    小米5s.png

    并不是所有布局都上移,所以不要所有情况都加padding,否则低版本就会像下面这样


    魅族Mx3.png

    只需在布局文件中设置fitsSystemWindows就可以了

     android:fitsSystemWindows="true"
    

    Fragment布局中加入fitsSystemWindows无效

    有些底部导航栏布局中会有多个Fragment,fitsSystemWindows设置无效,建议在布局中添加与状态栏等高的padding

    注:这里需要判断下,因为Android4.4以下布局不会上移

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //添加padding
    }
    
      /**
         * 获取状态栏高度,在页面还没有显示出来之前
         *
         * @param a
         * @return
         */
        public static int getStateBarHeight(Context a) {
            int result = 0;
            int resourceId = a.getResources().getIdentifier("status_bar_height",
                    "dimen", "android");
            if (resourceId > 0) {
                result = a.getResources().getDimensionPixelSize(resourceId);
            }
            return result;
        }
    
    • 看看效果吧
    标题栏.gif

    测试结果

    以下为测试通过的机型,这里测试通过指的是程序无异常显示、并不是都实现了白底黑字
    
    // OPPO R9 Plustm A (5.1.1)
    // Huawei mate8 (7.0)
    // 金立 m5 (5.1)
    //Pixel(9)
    // 华为 P20(8.1.0)
    // 华为mate10 (8.0.0)
    //nova 2 (7.0)
    //小米 5s (6.0.1)
    //夜神模拟器(4.4.2)
    //魅族M5 (6.0)
    //小米2s (5.0.2)
    //vivo Y31A(5.1.1)
    //oppo A33 (5.1.1)
    //魅蓝m1 (4.4.4)
    //魅族Mx3(4.2.1)
    //华为荣耀6 (4.4.2)
    //酷派8109 (4.0.3)
    //三星note3(4.3)
    

    Pixel(android 9.0)状态栏不知道为什么这么高、但图标都在中间应该没问题吧


    Pixel.png

    Demo

    github:https://github.com/forvv231/EasyTitleBar.git

    apk: https://fir.im/EasyTitleBar

    image.png

    By the Way

    Demo中快速实现底部导航栏,参考几行代码实现Android底部导航栏(带加号、红点提示、数字消息)

    通用标题栏实现,参考打造Android通用标题栏(轻松向左右两侧添加Menu)


    点个赞吧

    在一起之后就再没有自己系过鞋带,再没有自己拧过瓶盖,再没有自己洗过水果…

    怎么,给你打残废了吗?

    相关文章

      网友评论

      • 但求无愧于心_ad3d:三星手机不行 6.0系统 状态栏字体颜色还是白色
      • Villa__Mou:小米和魅族4.4以上可以,其他要5.0以上
        Vincent7Wong:@villa_mou7 我之前就尝试做过、没太弄明白、出现适配问题了、一急就不弄了。我所希望的不过是能变白底黑字就变、不能变就还是白字但不能是白底、现在应该没什么问题吧;
        Villa__Mou:@丶ZHI念 对,说错了,是6.0,上次我也遇到这个需求,但是适配不完后面就改了
        Vincent7Wong:你说白底黑字么、除了小米魅族、Android得6.0以上、但有些应用、oppo还是vivo(6.0以下)也可以、网上搜oppo、vivo的没找不到
      • AWeiLoveAndroid:纠结这个没用 一般开发中只看沉浸式状态栏 更多的是设置背景色
        Vincent7Wong:但、确实有这需求啊

      本文标题:白底黑字状态栏(详细使用步骤及各机型测试结果)

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