美文网首页Android开发经验谈Android开发Android开发
android4.4以上的状态栏背景和文字颜色的修改记录

android4.4以上的状态栏背景和文字颜色的修改记录

作者: space0o0 | 来源:发表于2019-01-31 10:23 被阅读14次

    4.4以上

    Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT

    先使用 FLAG_TRANSLUCENT_STATUS 设置状态栏透明

    然后用一个期望的背景色view填充statusBar

    同时使用 setFitsSystemWindows 让标题栏下移,否则标题栏和状态栏会重叠

        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        private static void setStatusBarBackground_V19(Activity activity, int color) {
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        
            ViewGroup decorViewGroup = (ViewGroup) window.getDecorView();
            View statusBarView = new View(window.getContext());
            //获取statusBar高度
            int statusBarHeight = getStatusBarHeight(window.getContext());
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, statusBarHeight);
            params.gravity = Gravity.TOP;
            statusBarView.setLayoutParams(params);
            statusBarView.setBackgroundColor(color);
            decorViewGroup.addView(statusBarView);
            
            //设置标题栏下移
            ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
            rootView.setFitsSystemWindows(true);
            rootView.setClipToPadding(true);
        }
    

    5.0以上

    Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP

    可以使用 setStatusBarColor 方法直接修改

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        private static void setStatusBarBackground_V21(Activity activity, int color) {
            Window window = activity.getWindow();
            //首先清除默认的FLAG_TRANSLUCENT_STATUS
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(color);
        }
    

    6.0以上(浅色背景的适配)

    在6.0以上,谷歌新增了修改状态栏文字颜色的方法,当我们的状态栏颜色为浅色或接近状态栏文字颜色的时候,我们就可以把状态栏的文字改成深色。

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             //修改为深色,因为我们把状态栏的背景色修改为主题色白色,默认的文字及图标颜色为白色,导致看不到了。
             activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }
    

    其他机型的适配(小米,魅族)

    小米

    小米手机的系统版本是在android6.0以后的,使用系统的修改方式

    即:

    setSystemUiVisibility  -> 修改状态栏文字颜色
    
    setStatusBarColor -> 修改状态栏背景色
    

    其他版本中,小米提供了自己的方法修改状态栏文字颜色,修改背景色使用系统的方法

    Build.VERSION.SDK_INT >= Build.VERSION_CODES.M

        static boolean MIUISetStatusBarLightMode(Activity activity, boolean darkmode) {
            boolean result = false;
            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);
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    
        //判断是miui7以上的
        private static boolean isMiUIV7OrAbove() {
            try {
                final Properties properties = new Properties();
                properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
                String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null);
                if (uiCode != null) {
                    int code = Integer.parseInt(uiCode);
                    return code >= 5;
                } else {
                    return false;
                }
    
            } catch (final Exception e) {
                return false;
            }
        }
    
    
        //判断是miui6以上的
        private static boolean isMiUIV6OrAbove() {
            try {
                final Properties properties = new Properties();
                properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
                String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null);
                if (uiCode != null) {
                    int code = Integer.parseInt(uiCode);
                    return code >= 4;
                } else {
                    return false;
                }
    
            } catch (final Exception e) {
                return false;
            }
        }
    

    魅族

    魅族提供自己的方法修改状态栏文字颜色

    状态栏背景色使用系统默认的

        static boolean FlymeSetStatusBarLightMode(Activity activity, boolean darkmode) {
            boolean result = false;
            try {
                WindowManager.LayoutParams lp = 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(lp);
                if (darkmode) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                activity.getWindow().setAttributes(lp);
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    
        //判断魅族系统
        private static boolean isFlymeV4OrAbove() {
            String displayId = Build.DISPLAY;
            if (!TextUtils.isEmpty(displayId) && displayId.contains("Flyme")) {
                String[] displayIdArray = displayId.split(" ");
                for (String temp : displayIdArray) {
                    //版本号4以上,形如4.x.
                    if (temp.matches("^[4-9]\\.(\\d+\\.)+\\S*")) {
                        return true;
                    }
                }
            }
            return false;
        }
    

    贴下代码

    public class StatusBarUtils {
    
        public static void setLightStatusBar(Activity activity) {
            final int white = ContextCompat.getColor(activity, R.color.white);
            final int gray = ContextCompat.getColor(activity, R.color.graymin);
            final int testColor=ContextCompat.getColor(activity,R.color.blue);
    
            if (isMiUIV7OrAbove()) {
                //设置状态栏文字黑色
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                    //设置状态栏颜色
                    setStatusBarBackground_V21(activity, white);
                }else {
                    MIUISetStatusBarLightMode(activity,true);
                    setStatusBarBackground_V19(activity,white);
                }
    
                return;
            } else if (isMiUIV6OrAbove()) {
                MIUISetStatusBarLightMode(activity, true);
                setStatusBarBackground_V19(activity,white);
    
                return;
            }
    
            if (isFlymeV4OrAbove()){
                FlymeSetStatusBarLightMode(activity,true);
                setStatusBarBackground_V19(activity,white);
    
                return;
            }
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                //api23+ 6.0以上的
                //设置状态栏文字黑色
                activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                //设置状态栏颜色
                setStatusBarBackground_V21(activity, white);
    
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //api21-23   5.0~6.0
                //字体不能变色,所以statusBar颜色改成灰的
                setStatusBarBackground_V21(activity, gray);
    
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                //api19-21
                setStatusBarBackground_V19(activity, gray);
            }
    
        }
    
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        private static void setStatusBarBackground_V21(Activity activity, int color) {
            Window window = activity.getWindow();
            //首先清除默认的FLAG_TRANSLUCENT_STATUS
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(color);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        private static void setStatusBarBackground_V19(Activity activity, int color) {
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    
            ViewGroup decorViewGroup = (ViewGroup) window.getDecorView();
            View statusBarView = new View(window.getContext());
            int statusBarHeight = getStatusBarHeight(window.getContext());
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, statusBarHeight);
            params.gravity = Gravity.TOP;
            statusBarView.setLayoutParams(params);
            statusBarView.setBackgroundColor(color);
    
            decorViewGroup.addView(statusBarView);
    
            //设置标题栏下移
            ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
            rootView.setFitsSystemWindows(true);
            rootView.setClipToPadding(true);
        }
    
        private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
    
        private static boolean isMiUIV6OrAbove() {
            try {
                final Properties properties = new Properties();
                properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
                String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null);
                if (uiCode != null) {
                    int code = Integer.parseInt(uiCode);
                    return code >= 4;
                } else {
                    return false;
                }
    
            } catch (final Exception e) {
                return false;
            }
        }
    
        private static boolean isMiUIV7OrAbove() {
            try {
                final Properties properties = new Properties();
                properties.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
                String uiCode = properties.getProperty(KEY_MIUI_VERSION_CODE, null);
                if (uiCode != null) {
                    int code = Integer.parseInt(uiCode);
                    return code >= 5;
                } else {
                    return false;
                }
    
            } catch (final Exception e) {
                return false;
            }
        }
    
        private static boolean isFlymeV4OrAbove() {
            String displayId = Build.DISPLAY;
            if (!TextUtils.isEmpty(displayId) && displayId.contains("Flyme")) {
                String[] displayIdArray = displayId.split(" ");
                for (String temp : displayIdArray) {
                    //版本号4以上,形如4.x.
                    if (temp.matches("^[4-9]\\.(\\d+\\.)+\\S*")) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        static boolean MIUISetStatusBarLightMode(Activity activity, boolean darkmode) {
            boolean result = false;
            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);
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    
        static boolean FlymeSetStatusBarLightMode(Activity activity, boolean darkmode) {
            boolean result = false;
            try {
                WindowManager.LayoutParams lp = 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(lp);
                if (darkmode) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                activity.getWindow().setAttributes(lp);
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    
        private static int getStatusBarHeight(Context context) {
            int statusBarHeight = 0;
            Resources res = context.getResources();
            int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
                statusBarHeight = res.getDimensionPixelSize(resourceId);
            }
            return statusBarHeight;
        }
    }
    

    --

    参考文档:

    Android关于沉浸式状态栏的一些总结

    Android修改状态栏颜色全方位教程

    相关文章

      网友评论

        本文标题:android4.4以上的状态栏背景和文字颜色的修改记录

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