You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android 12 Theme.SplashScreen启动屏在小米MIUI强制深色模式下失效的解决方案咨询

解决MIUI强制深色模式下Android 12 SplashScreen失效的问题

我之前在适配Android 12启动屏时,也碰到过和你一模一样的问题——用Theme.SplashScreen实现的启动屏,在小米MIUI开启强制深色模式后完全失效,设置android:forceDarkAllowed="false"根本不管用。折腾了好几天,总结出几个亲测有效的方案:

方案一:添加MIUI专属的强制深色禁用属性

MIUI的强制深色模式有自己的私有逻辑,原生系统的forceDarkAllowed属性经常被忽略。你可以在启动屏的主题中额外添加MIUI专属的属性:

<style name="SplashTheme" parent="Theme.SplashScreen">
    <!-- 原生系统属性 -->
    <item name="android:forceDarkAllowed">false</item>
    <!-- MIUI专属属性,禁用强制深色 -->
    <item name="miui:forceDarkAllowed">false</item>
    <!-- 其他启动屏配置,比如windowSplashScreenBackground、windowSplashScreenAnimatedIcon等 -->
</style>

注意要确保你的主题正确继承自Theme.SplashScreen,并且这个主题已经应用在启动屏Activity上。

方案二:在启动屏Activity中动态禁用深色模式

如果方案一还是不行,可以尝试在启动屏Activity的onCreate方法调用super.onCreate之前,通过代码强制禁用深色模式,同时针对MIUI做特殊适配:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // 先处理MIUI的强制深色问题
    if (isMIUIDevice()) {
        try {
            // 利用MIUI的私有API,禁止状态栏颜色被强制修改
            Class<?> miuiLayoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
            Field extraFlagField = miuiLayoutParams.getField("EXTRA_FLAG_FORCE_NOT_CHANGE_STATUS_BAR_COLOR");
            int flag = extraFlagField.getInt(miuiLayoutParams);
            getWindow().addFlags(flag);
        } catch (Exception e) {
            // 捕获异常,避免MIUI版本差异导致崩溃
            e.printStackTrace();
        }
    }

    // 针对Android Q及以上,设置浅色状态栏(如果你的启动屏是浅色背景)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        getWindow().getInsetsController().setSystemBarsAppearance(
                WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
                WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
    }

    // 再调用super.onCreate
    super.onCreate(savedInstanceState);

    // 后续的启动屏跳转逻辑
    // ...
}

// 判断是否是MIUI设备
private boolean isMIUIDevice() {
    return "Xiaomi".equalsIgnoreCase(Build.MANUFACTURER);
}

这个方法通过MIUI的私有API强制锁定状态栏颜色,避免被强制深色模式修改,同时保证启动屏的视觉效果符合预期。

方案三:使用固定Drawable作为启动屏背景

如果上面两个方案都没效果,你可以彻底绕过主题颜色的影响,直接用固定的Drawable作为启动屏背景。比如创建一个splash_background.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 固定的背景色,不会被深色模式修改 -->
    <item android:drawable="@color/splash_background_color" />
    <!-- 居中的启动图标 -->
    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/ic_splash_icon" />
    </item>
</layer-list>

然后在启动屏主题中设置:

<style name="SplashTheme" parent="Theme.SplashScreen">
    <item name="android:windowBackground">@drawable/splash_background</item>
    <!-- 禁用系统深色适配 -->
    <item name="android:forceDarkAllowed">false</item>
    <item name="miui:forceDarkAllowed">false</item>
</style>

这种方法直接用固定的颜色和图标,完全不受深色模式的影响,适合对启动屏视觉一致性要求高的场景。

为什么android:forceDarkAllowed没用?

主要是因为MIUI的强制深色模式实现和原生Android差异很大,它有自己的一套资源替换逻辑,经常会忽略原生系统的深色模式控制属性,所以必须针对性适配。

内容的提问来源于stack exchange,提问作者Valery Boretsky

火山引擎 最新活动