在Android 12 出現了一個SplashScreen新功能,它為所有應用添加了新的應用啟動動畫,可以通過SplashScreen API來定制專屬應用啟動動畫。
默認情況下,新的應用啟動動畫為白色背景,中心為應用圖標。
接下去將一一介紹如何使用SplashScreen API來定制專屬應用啟動動畫。
由于這是Android 12新增功能,所以所有相關API都要求api 31才能使用,因此需要額外創建一個values-v31,并將themes.xml拷貝一份放入其中。
背景顏色
默認情況下,應用啟動動畫背景為白色。
在應用所使用的主題中設置以下代碼,可以定制應用啟動動畫的背景顏色。
<item name="android:windowSplashScreenBackground">@color/splash_screen_background</item>
<color name="splash_screen_background">#7B5AB6</color>
需要注意一點,目前使用android:windowSplashScreenBackground設置的顏色不能帶透明度,必須為6位或者是8位且透明度為FF,如果使用了帶透明度的顏色將不生效。
啟動圖標
默認情況下,應用啟動動畫的中心為應用圖標。
在應用所使用的主題中設置以下代碼,可以定制應用啟動動畫的中心圖標。
<item name="android:windowSplashScreenAnimatedIcon">@drawable/cat</item>
這是原始圖片:
- 可以發現啟動圖標需要保留一定的內邊距,因為會被部分裁剪。
- 除了設置靜態圖片,也可以設置動畫形式,配置使用android:windowSplashScreenAnimationDuration設置動畫時長。
- 如果設置的圖標是透明背景的,可以另外設置android:windowSplashScreenIconBackgroundColor來定制中心圖標的背景顏色。
底部圖片(Google不推薦使用)
使用android:windowSplashScreenBrandingImage可以設置底部圖片,圖片尺寸比例需要為2.5:1。
延緩啟動時間
使用android:windowSplashScreenAnimationDuration可以設置啟動動畫時長,但是最長只能設置1000毫秒。
很多時候需要在啟動的時候拉取一些應用配置,需要有更長時間的啟動效果。
可以在代碼中實現,通過ViewTreeObserver.OnPreDrawListener:
class MainActivity : AppCompatActivity() {
private var isAppReady = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val content: View = findViewById(android.R.id.content)
content.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
if (isAppReady) {
content.viewTreeObserver.removeOnPreDrawListener(this)
}
return isAppReady
}
})
delayBootTime()
}
private fun delayBootTime() {
lifecycleScope.launch {
delay(3000)
isAppReady = true
}
}
}
當應用配置已準備好,onPreDraw返回true,并且移除監聽。這里使用delay3秒來模擬拉取應用配置的耗時操作。
需要注意,一定要在準備好后onPreDraw返回true,否則會一直卡在啟動頁上。
啟動退出動畫
Android 12 SplashScreen新功能提供了setOnExitAnimationListener方法可以定制啟動退出時的動畫效果,該API只能在版本12及以上使用:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
splashScreen.setOnExitAnimationListener { splashScreenView ->
val slideUp = ObjectAnimator.ofFloat(
splashScreenView,
View.TRANSLATION_Y,
0f,
-splashScreenView.height.toFloat()
)
slideUp.duration = 2000
// 在自定義動畫結束時調用splashScreenView.remove()
slideUp.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
splashScreenView.remove()
}
})
slideUp.start()
}
}
低版本兼容
在Android 12以下版本沒有SplashScreen啟動動畫,顯示的空白背景頁面,這在用戶體驗上很不好。因此,Google在AndroidX中提供了一個向下兼容的SplashScreen庫。
配置
implementation 'androidx.core:core-splashscreen:1.0.0'
設置主題
定義一個新的主題并給應用使用:
<style name="SplashScreenTheme" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/splash_screen_background</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/cat</item>
<item name="postSplashScreenTheme">@style/Theme.SplashScreenDemo</item>
</style>
需要注意幾點:
- 必須以R.style.Theme_SplashScreen 為父級
- 啟動圖標動畫形式失效
- windowSplashScreenBackground、windowSplashScreenAnimatedIcon前面都沒有 android:
- postSplashScreenTheme指定應用原來的主題,這樣,當SplashScreen結束時,應用主題能夠被恢復
在啟動Activity中設置
一定要在setContentView方法之前調用installSplashScreen方法,由于在Compose中setContentView方法在super.onCreate()內部調用,因此建議在 super.onCreate()之前調用 installSplashScreen。
installSplashScreen()
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
至此,在低版本上也能有同樣效果的SplashScreen動畫了,當然一些啟動退出動畫這些Android 12特有的API仍然是無法使用的。