Android SplashScreen

3,484 阅读3分钟

SplashScreen

顾名思义启动画面,在Android 12的时候,谷歌推出了SplashScreen,目的是解决APP第一次启动的时候会强制白屏。 在Android 13的时候,Android系统对App的启动增加了默认的SplashScreen,如果没有自定义SplashScreen,那么就会用App的launcher图片来作为SplashScreen的元素进行展示。

启动画面的元素和机制

启动画面的元素由 Android 清单文件中的 XML 资源文件定义。每种元素都有浅色模式和深色模式版本。

启动画面的可自定义元素包括应用图标、图标背景和窗口背景:

显示启动画面中包含的元素的图片

图 1.  启动画面的可自定义元素。

请考虑以下元素,如图 2 所示:

中心图标这个图标必须是可以获取到的Drawable对象,可以是静态图片(webp/png/jpg),也可以是是个vector的xml。做为vector的时候可以是静态的,也可以是有动画效果。这个动画的时长可以不受限制,但谷歌的建议是不超过 1000 毫秒。如果没配置启动器图标为默认图标。

图标背景是可选的,当需要强调中心图标的时候很有用。如果是App的图标是采用的自适应图标,就可以把自适应图标的背景直接设置进去。可以是灵活的drawble也可以是color

遮盖层会把中心图标和图标背景的大小裁剪成版本为图标宽高2/3的圆形。

但是我在iqoo的手机上发现遮盖层并没有裁剪成圆形,而是大小不变的情况下裁剪成了圆角图标的样子。

image.png

窗口背景由不透明的单色组成。如果窗口背景已设置且为纯色,且未设置相应属性,则默认使用该背景。

启动画面尺寸

启动画面图标使用的规范与自适应图标相同,如下所示:

  • 品牌图片:尺寸必须为 200×80 dp。这个显示在底部位置。
  • 具有图标背景的应用图标:显示尺寸必须为 240×240 dp,且位于直径 160 dp 的圆圈内。
  • 无图标背景的应用图标:显示尺寸必须为 288×288 dp,并且位于直径 192 dp 的圆圈内。

这里推荐设计稿以300×300 dp尺寸进行设计,然后把图标放在直径为200dp的圆圈内。圆圈以外的所有内容都会变为不可见(已遮盖)。(iqoo Android 13遮盖并不是圆的,但还是建议以圆圈遮盖进行设计。)

集成内容

dependencies {
    implementation "androidx.core:core-splashscreen:1.0.0"
}

在启动的Activity中增加installSplashScreen(),这个方法需要写在setContentView之前

  override fun onCreate(savedInstanceState: Bundle?) {
        val splashScreen = installSplashScreen()
        WindowCompat.setDecorFitsSystemWindows(window, false)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            // Disable the Android splash screen fade out animation to avoid
            // a flicker before the similar frame is drawn in Flutter.
            splashScreen.setOnExitAnimationListener { splashScreenView -> splashScreenView.remove() }
        }
        super.onCreate(savedInstanceState)
    }

设置style

<!-- 这个是注册的Activity实际的theme -->
    <style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:navigationBarColor">@android:color/transparent</item>
        <item name="android:windowLightNavigationBar">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:enforceNavigationBarContrast">false</item>
    </style>
   
    
    <style name="Theme.App.Starting" parent="Theme.SplashScreen">

        <item name="windowSplashScreenBackground">@color/brand_color</item>
      
        <item name="windowSplashScreenAnimatedIcon">@drawable/launcher_logo</item>
        <item name="windowSplashScreenAnimationDuration">200</item>
        <!-- 这个是启动Activity实际的Theme Style-->
        <item name="postSplashScreenTheme">@style/LaunchTheme</item>
    </style>

Manifest.xml启动Activity或者Applicationstyle设置Theme.App.Starting

<activity
    android:name=".MainActivity" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
    android:exported="true"
    android:hardwareAccelerated="true"
    android:launchMode="singleTop"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.App.Starting"
    android:windowSoftInputMode="adjustResize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>    

postSplashScreenTheme在SplashScreen的Api中设置给了启动Activity

protected fun setPostSplashScreenTheme(
    currentTheme: Resources.Theme,
    typedValue: TypedValue
) {
    if (currentTheme.resolveAttribute(R.attr.postSplashScreenTheme, typedValue, true)) {
        finalThemeId = typedValue.resourceId
        if (finalThemeId != 0) {
            activity.setTheme(finalThemeId)
        }
    }
}