Android 状态栏颜色兼容方案

一、需求

由于Android系统碎片化比较严重,因此为了统一调整状态栏颜色,因此实现一个工具类相当必要。

 

注意:本类支持Android 5.0 以上的版本,android 5.0之前的兼容性太差,因此不做处理。

public class StatusBarManager {

    private int is_MIUI_platform = -1; //初始值是-1,0表示检测过不是改平台,1表示检测过时该平台
    private int is_MEIZU_platform = -1; //初始值是-1,0表示检测过不是改平台,1表示检测过时该平台


    public static final int UI_FIT_SYSTEM_WINDOW =  0x01; //全屏模式
    public static final int UI_FIT_ACTIVITY =  0x00; //着色模式
    private static ColorDrawable colorDrawable;



    public static volatile   SoftReference<Integer> statusBarHeightSoftRef = new SoftReference<Integer>(-1);

   public static  StatusBarManager  shareInstance;

    protected StatusBarManager(){

    }


    private  StatusBarManager updateStatusBarTheme(Activity activity, @ColorInt int color, @IntRange(to =UI_FIT_SYSTEM_WINDOW,from=UI_FIT_ACTIVITY) int mode) {
        if (activity == null) return null;
        if(shouldUsed()){
            setStatusBarColor(activity, color,mode);
        }
        return this;
    }


    public static boolean shouldUsed() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
    }



    public static StatusBarManager updateStatusBarTheme(Activity activity, StatusBarAdapter adapter) {
        if (activity == null || adapter==null) return null;
        final int statusBarColor = adapter.getStatusBarColor();
        final int statusBarMode = adapter.getStatusBarMode();

        return shareInstance().updateStatusBarTheme(activity,statusBarColor,statusBarMode);
    }

    public synchronized static StatusBarManager shareInstance() {
        if (shareInstance==null){
            shareInstance = new StatusBarManager();
        }
        return shareInstance;
    }

    public int getStatusBarColor(Activity activity){
        if(!shouldUsed()) return Color.BLACK;
        Window window = activity.getWindow();
        if(window==null) return Color.BLACK;

        return window.getStatusBarColor();
    }
    public int getStatusBarMode(Activity activity){
        if(!shouldUsed()) return UI_FIT_ACTIVITY;
        Window window = activity.getWindow();
        if(window==null) return UI_FIT_ACTIVITY;
        final View decorView = activity.getWindow().getDecorView();
        if(decorView==null) return UI_FIT_ACTIVITY;
        int visibility = decorView.getSystemUiVisibility();

        if( (visibility & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)!=0){
            return UI_FIT_SYSTEM_WINDOW;
        }
        return UI_FIT_ACTIVITY;
    }


    private static void setStatusBarColor(Activity activity, @ColorInt int color,@IntRange(to =UI_FIT_SYSTEM_WINDOW,from=UI_FIT_ACTIVITY) int mode) {
        setStatusFeatures(activity,color,mode);
        int colorNav;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            colorNav = activity.getResources().getColor(R.color.color_navigation_bar_color, activity.getTheme());
        } else {
            colorNav = Utils.getResourcesColor(R.color.color_navigation_bar_color);
        }
        if(colorDrawable==null){
            colorDrawable = new ColorDrawable(colorNav);
        }else{
            colorDrawable.setColor(colorNav);
        }
        if(activity instanceof AppCompatActivity) {
            if (((AppCompatActivity)activity).getSupportActionBar() != null) {
                ((AppCompatActivity)activity).getSupportActionBar().setBackgroundDrawable(colorDrawable);
            }
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //设置状态栏颜色
              //  activity.getWindow().setStatusBarColor(shiftColor(color, 0.9f));
                activity.getWindow().setStatusBarColor(color);
                //设置导航栏(Actionbar,底部虚拟按键导航)颜色
                activity.getWindow().setNavigationBarColor(colorNav);
            }
    }



    private static void setStatusFeatures(Activity activity,@ColorInt int color,int mode) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)  return;
        Window window =  activity.getWindow();
        //取消状态栏透明
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        //添加Flag把状态栏设为可绘制模式
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

        //设置系统状态栏处于可见状态时位子的颜色

       // if(isLightColor(color)) {
            int flags =NcfColorUtils.isLightColor(color)?View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : View.SYSTEM_UI_FLAG_LAYOUT_STABLE; //判断是否为亮色,如果为亮色,则文字为黑色,反之为白色

            if(mode==UI_FIT_ACTIVITY) {
                flags |= View.SYSTEM_UI_FLAG_VISIBLE; //内容区非全屏模式
            }else{
                flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; //内容区全屏模式,内容区显示到状态栏下方
            }
        final View decorView = window.getDecorView();
        if(decorView.getSystemUiVisibility()!= flags) {
            decorView.setSystemUiVisibility(flags);
        }
        if(isXiaomi()) {
            setMIUIStatusBarDarkMode(NcfColorUtils.isLightColor(color), activity);
        }else if(isMeizu()){
            setMeizuStatusBar(NcfColorUtils.isLightColor(color), activity);
        }

        //让view不根据系统窗口来调整自己的布局
        ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT);
        View mChildView = mContentView.getChildAt(0);
        if (mChildView != null) {
            if(mChildView.getFitsSystemWindows()) {
                mChildView.setFitsSystemWindows(false);
            }
            ViewCompat.requestApplyInsets(mChildView);
        }
    }

    // 设置魅族状态栏
    public static void setMeizuStatusBar( boolean isLightStatusBar,Activity activity) {

        try {
            if(StatusBarManager.shareInstance().is_MEIZU_platform==0) return;
            StatusBarManager.shareInstance().is_MEIZU_platform = 0;
            final Window window = activity.getWindow();
            WindowManager.LayoutParams params = 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(params);
            if (isLightStatusBar) {
                value |= bit;
            } else {
                value &= ~bit;
            }
            meizuFlags.setInt(params, value);
            window.setAttributes(params);
            darkFlag.setAccessible(false);
            meizuFlags.setAccessible(false);
            StatusBarManager.shareInstance().is_MEIZU_platform = 1;
        } catch (Exception e) {
            e.printStackTrace();
            StatusBarManager.shareInstance().is_MEIZU_platform = 0;
        }
    }


    public static void setMIUIStatusBarDarkMode(boolean darkmode, Activity activity) {
        Class<? extends Window> clazz = activity.getWindow().getClass();
        try {
            if(StatusBarManager.shareInstance().is_MIUI_platform==0) return;
            int darkModeFlag = 0;
            StatusBarManager.shareInstance().is_MIUI_platform = 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);
            StatusBarManager.shareInstance().is_MIUI_platform = 1;
        } catch (Exception e) {
            StatusBarManager.shareInstance().is_MIUI_platform = 0;
            e.printStackTrace();
            return;
        }
    }
    // 是否是小米手机
    public static boolean isXiaomi() {
        return "Xiaomi".equals(Build.MANUFACTURER);
    }
    // 是否是魅族手机
    public static boolean isMeizu() {
        try {
            Method method = Build.class.getMethod("hasSmartBar");
            return method != null;
        } catch (NoSuchMethodException e) {
        }
        return false;
    }

    public static int getStatusBarHeight(Context context) {
        int statusBarHeight = (statusBarHeightSoftRef!=null)?statusBarHeightSoftRef.get():-1;
        if(statusBarHeight>0) return statusBarHeight;
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = res.getDimensionPixelSize(resourceId);
        }else{
            statusBarHeight = getStatusBarHeightWithoutRef(context);
        }
        statusBarHeightSoftRef = new SoftReference<Integer>(statusBarHeight);
        return statusBarHeight;
    }
    public static int getStatusBarHeightWithoutRef(Context context) {
        int statusBarHeight = 0;
        try {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            int height = Integer.parseInt(clazz.getField("status_bar_height")
                    .get(object).toString());
            statusBarHeight = context.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusBarHeight;
    }

 //判断颜色是否为亮色
public static boolean isLightColor(@ColorInt int color){
        int red = Color.red(color);
        int blue = Color.blue(color);
        int green = Color.green(color);
        int alpha = Color.alpha(color);
        if(alpha<51){
            return true;
        }
        return (red*0.299 + blue*0.578 + green*0.114) >= 192;
    }

}

适配器

    public  interface   StatusBarAdapter {
        public @IntRange(from=UI_FIT_ACTIVITY,to =UI_FIT_SYSTEM_WINDOW)  int getStatusBarMode();
        public  @ColorInt  int getStatusBarColor();
    }

 

 

参考博客:

https://www.jianshu.com/p/bae25b5eb867

https://www.jianshu.com/p/932568ed31af

https://juejin.im/post/5a30f1535188251c11409d77

https://www.jianshu.com/p/035a7e19fd9b

 

    原文作者:移动开发
    原文地址: https://my.oschina.net/ososchina/blog/3042670
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞