You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 12/12L禁用启动页过渡动画后windowLightStatusBar失效求助

解决Android 12/12L中SplashScreen退出动画禁用导致系统栏文字颜色失效的问题

问题背景

我配置了Theme.SystemBarColors主题,让系统栏背景在明暗模式下均匹配主题背景,单独使用时各Android版本表现正常。为实现系统启动页与应用内启动页的无缝切换,在Android 12+的onCreate中调用getSplashScreen().setOnExitAnimationListener(SplashScreenView::remove)禁用启动页退出动画,但这导致Android 12/12L上windowLightStatusBar和windowLightNavigationBar属性失效:系统栏背景颜色正常,但文字变为白色搭配浅背景,出现异常显示。该问题仅在系统启动页实际显示时触发(如从桌面启动应用),Android Studio直接启动则无异常,且Android 13中不存在此问题。

主题配置代码(values-v27/styles.xml):

<style name="Theme.SystemBarColors" parent="Theme.AppCompat.DayNight.NoActionBar">
  <item name="android:statusBarColor">?android:attr/colorBackground</item>
  <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
  <item name="android:navigationBarColor">?android:attr/colorBackground</item>
  <item name="android:windowLightNavigationBar">?attr/isLightTheme</item>
  <item name="android:windowDrawsSystemBarBackgrounds">true</item>
  <item name="android:windowTranslucentNavigation">false</item>
  <item name="android:windowTranslucentStatus">false</item>
</style>

调用的核心代码:

getSplashScreen().setOnExitAnimationListener(SplashScreenView::remove);

解决方案

方案1:手动重新应用系统栏文字颜色属性

直接移除SplashScreenView会打断系统对主题属性的应用流程,因此可以在移除后手动触发系统栏文字颜色的设置:

getSplashScreen().setOnExitAnimationListener { splashView ->
    // 移除启动页视图
    splashView.remove()
    // 手动重新设置系统栏文字颜色
    val window = window
    val isLightTheme = resources.getBoolean(R.bool.isLightTheme)
    window.decorView.systemUiVisibility = if (isLightTheme) {
        View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
    } else {
        0
    }
}

需确保isLightTheme在资源文件中正确配置:

  • values/bools.xml:<bool name="isLightTheme">true</bool>
  • values-night/bools.xml:<bool name="isLightTheme">false</bool>

方案2:通过空动画完成启动页退出

避免直接调用remove(),而是通过极短的透明动画完成退出流程,让系统正常处理主题属性过渡:

getSplashScreen().setOnExitAnimationListener { splashView ->
    splashView.animate()
        .alpha(0f)
        .setDuration(1) // 视觉上无感知的短时长
        .withEndAction { splashView.remove() }
        .start()
}

这种方式既实现了无缝切换的视觉效果,又保证系统完整执行启动页退出的属性应用逻辑。

方案3:针对Android 12/12L做版本适配

仅在Android 12和12L上使用修复逻辑,Android 13及以上保持原有代码:

if (Build.VERSION.SDK_INT in Build.VERSION_CODES.S..Build.VERSION_CODES.S_V2) {
    getSplashScreen().setOnExitAnimationListener { splashView ->
        splashView.animate()
            .alpha(0f)
            .setDuration(1)
            .withEndAction { splashView.remove() }
            .start()
    }
} else {
    getSplashScreen().setOnExitAnimationListener(SplashScreenView::remove)
}

问题原理

Android 12/12L的SplashScreen框架在直接调用remove()时,会提前终止系统栏主题属性的应用流程,导致windowLightStatusBar这类依赖视图树更新的属性未被正确加载。通过延迟手动设置或让动画正常完成,可让系统有足够时间处理这些属性的切换逻辑。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:10:31