Android沉浸式技术解决方案(白色沉浸背景,修改通知栏颜色),小米MIUI、魅族Flyme、Android6.0及以上兼容方式

这次app版本要实现沉浸式的功能,百度搜索一些方法,还是很容易可以实现的。但是设计师要求白色沉浸式,可是通知栏字体是白色所以就出现这样:

Android沉浸式技术解决方案(白色沉浸背景,修改通知栏颜色),小米MIUI、魅族Flyme、Android6.0及以上兼容方式_第1张图片
Screenshot_20170527-161932.png

若是红色、蓝色等都是好处理的,然而白色就必须让通知栏字体和图标颜色为灰色,我看了下的App白色沉浸式,通知栏字体改变为灰色,确实是有办法来实现的。

Google在Android4.4之后支持了可以改变通知栏背景,6.0才支持了通知栏的字体可修改为灰色,国内厂商也对底层进行了修改,小米和魅族有自己特定的修改方式。

沉浸式的工具类

public class StatusBarUtil {

    private static final int INVALID_VAL = -111;
    private static final int COLOR_DEFAULT = Color.parseColor("#ffffff");


    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static void compat(Activity activity, int statusColor)
    {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        {
            int color = COLOR_DEFAULT;
            if (statusColor != INVALID_VAL)
            {
                activity.getWindow().setStatusBarColor(statusColor);
            }else {
                activity.getWindow().setStatusBarColor(color);
            }
            return;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
        {
            int color = COLOR_DEFAULT;
            ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
            if (statusColor != INVALID_VAL)
            {
                color = statusColor;
            }
            View statusBarView = new View(activity);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    getStatusBarHeight(activity));
            statusBarView.setBackgroundColor(color);
            contentView.addView(statusBarView, lp);
        }

    }


    public static void compat(Activity activity)
    {
        compat(activity, INVALID_VAL);
    }


    public static int getStatusBarHeight(Context context)
    {
        int result = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0)
        {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
    /**
     * 小米MIUI系统 亲测好用
     * @param window
     * @param dark
     * @return
     */
    public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
        boolean result = false;
        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;
            }catch (Exception e){

            }
        }
        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;
    }

    /**
     * Android 6.0以上系统 修改状态栏字体颜色
     */
    public static void android6_SetStatusBarLightMode(Window window) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
            window.setStatusBarColor(Color.TRANSPARENT);
        }
    }

}```

在BaseActivity中添加判断代码

/**
* 沉浸式处理方案
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (StatusBarUtil.MIUISetStatusBarLightMode(getWindow(),true)) {//小米MIUI系统
StatusBarUtil.compat(this);
}
else if (StatusBarUtil.FlymeSetStatusBarLightMode(getWindow(),true)) {//魅族flyme系统
StatusBarUtil.compat(this);
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//Android6.0以上系统
StatusBarUtil.android6_SetStatusBarLightMode(getWindow());
StatusBarUtil.compat(this);
}
}

我测试了两个手机,小米MiUI系统6.0,走的是小米特定的处理方法可实现,虽然是Android6.0,小米机使用``` else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//Android6.0以上系统
                StatusBarUtil.android6_SetStatusBarLightMode(getWindow());
                StatusBarUtil.compat(this);
            }```无效。华为手机7.0,走6.0之后的API可实现。因为没有魅族手,没有测试过,可以测下,如果好用也告诉我下。
这两天也是查了一些资料,走过一些坑,分享总结下。

![Screenshot_20170527-162039.png](http://upload-images.jianshu.io/upload_images/2825322-7f4e1a1830d2f139.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
其实大多数App是没有用白色当标题的吧,这样会容易得多,不用处理那么多的兼容性问题

你可能感兴趣的:(Android沉浸式技术解决方案(白色沉浸背景,修改通知栏颜色),小米MIUI、魅族Flyme、Android6.0及以上兼容方式)