欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 主流 app 的沉浸式效果

程序员文章站 2022-06-19 13:10:08
什么是沉浸式呢?就是状态栏透明,将 activity 布局延伸到整个屏幕,所呈现的一种模式效果。...

什么是沉浸式呢?就是状态栏透明,将 activity 布局延伸到整个屏幕,所呈现的一种模式效果。

白底黑字式

状态栏透明,深色图标文字是地图 app 常见效果:
Android 主流 app 的沉浸式效果
关于状态栏的展示效果,官方也是调整多多。在 android4.4 版本之前,用户除了通过全屏模式使之消失外,并不能对状态栏操作什么。而在 android5.0 之前,官方提供了 FLAG_TRANSLUCENT_STATUS 标志位,来控制状态栏是否实现渐变的半透明效果。而到了 android5.0 之后,FLAG_TRANSLUCENT_STATUS 标志位所控制的样式也做了调整,从渐变变成了纯粹的半透明。而到了 android6.0 之后,FLAG_TRANSLUCENT_STATUS 效果再次改变,设置此标志可使状态栏全透明。

Android5.0 以上状态栏透明的代码示例:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // android 5.0+ 状态栏透明
        Window window = getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        window.getDecorView().setSystemUiVisibility(option);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.TRANSPARENT);
    }

考虑到状态栏被设置为透明后,状态栏上的文字和图标存在看不清的情况。Android6.0 以上,系统提供了API 来修改状态栏的字体背景色:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
        getWindow().getDecorView().setSystemUiVisibility(option);
    }

关于沉浸式,难点在于特殊机型的适配工作上。例如小米和魅族手机,在 android4.4 版本之后,FLAG_TRANSLUCENT_STATUS 标志位便显示为全透明效果,而且自 android4.4 之后,其便提供了设置状态栏图标和文字颜色的内部方法。

特殊(1)魅族

详情参考开放平台,下载 StatusbarColorUtils 类,接口见下:

    /**
     * 设置状态栏字体图标颜色
     *
     * @param activity 当前activity
     * @param dark     是否深色 true为深色 false 为白色
     */
    public static void setStatusBarDarkIcon(Activity activity, boolean dark) {
        setStatusBarDarkIcon(activity, dark, true);
    }
特殊(2)OPPO

详情参考开放平台,对 Android 版本是 6.0 及以后的 OPPO 机型,使用 Google 提供View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 的 Flag 来设置状态栏图标黑色显示效果。

对 Android5.1 版本并且是 ColorOS3.0 的 OPPO 机型使用 ColorOS 提供 SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT 的 Flag 来设置状态栏图标黑色效果,由于该标记未公开,开发者需要在应用代码中定义。

    final int SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT = 0x00000010;
    Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    window.getDecorView().setSystemUiVisibility(SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT);

为方便开发者对于 OPPO 机型的反色适配,提供了用于设置状态栏显示效果的接口方法,开发者可以根据应用需要动态设置状态栏图标为白色或是黑色。接口传入值 ture 时状态栏图标为黑色,接口转入值为 false 状态栏图标为白色:

    public void setLightStatusBarIcon(boolean lightMode) {
        Window window  = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        int vis = window.getDecorView().getSystemUiVisibility();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (lightMode) {
                vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            } else {
                vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.L) {
            if (lightMode) {
                vis |= SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT;
            } else {
                vis &= ~SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT;
            }
        }
        window.getDecorView().setSystemUiVisibility(vis);
    }
特殊(3)小米

详情参考开放平台,在 Android 6.0 以前,Android 没有方法可以实现“状态栏黑色字符”效果,因此 MIUI 自己做了一个接口。在 Android 6.0 及以上版本,Android 提供了标准的方法实现“状态栏黑色字符”效果,但这个方法和 MIUI 的方法产生了冲突。

在新的 MIUI 开发版 7.7.13 及以后版本(基于 Android 6.0 ),设置代码:

    Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

在旧的 MIUI 版本,仍然需要使用 MIUI 原有的方法,即:

    public void setStatusBarDarkMode(boolean darkmode, Activity activity) {
        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);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

待续

本文地址:https://blog.csdn.net/MingJieZuo/article/details/107870808