Android 12 Splash screen
last update 2021/10/20 (継続更新中)
OverView
Android 12からアプリの起動時にsplash screenが強制的に挿入されるようになりまりました。
本記事ではこのsplash screenの振る舞いとカスタマイズ方法について記します。
How the splach screen works
Splash screenが表示されるケース
- アプリのプロセスが実行されていない状態での起動(cold start)
- アプリのプロセスは実行されているがActivityが作られていない状態での起動(warm start)
Mechanics of the Splash screen
Contents
① アイコン
デフォルトでは、ランチャーアイコンが使用される。
またはVector drawableで描画可能なものを指定可能。
静止画でもアニメーションでもOK。
アニメーションの継続時間は無制限だが、1秒を超えないことを推奨されている。
② アイコン背景
アイコン背景領域。円形のアイコン設定の場合この領域も円形になる。
カスタム可能だが、アダプティブアイコンを設定している場合、そこで指定している背景が優先される。
③ アイコンの領域
アイコンが配置される領域。
アダプティブアイコン同様1/3がマスクされている
④ 背景
不透明な単色で描画される。
カスタム可能。
特に指定がない場合はウィンドウの背景色が適用される。
⑤ ブランディングイメージ
画面下部に表示される静止画。
カスタマイズできるように用意されて入るが、Googleが用意したデザインのガイドライン的には利用はオススメしないとのこと。
サイズは縦横80dp*200dpで確保される(深くおってないけど画面サイズに応じてリサイズされる場合がありそう?)
表示位置は画面下部から60dpの位置
Enter/Exit Animation
splash screenは開始アニメーションと終了アニメーションがシステムによって組み込まれています
開始アニメーション
splash screenを表示する際のアニメーション。
画面のfadeやアイコンの領域の位置変更など。
カスタマイズは不可
終了アニメーション
splash screenが終了する際のアニメーション。
カスタマイズは可能
変化、透明度、色を設定し、任意のアニメーションを実行することができます。
ただしカスタマイズした場合はsplash screenの終了タイミングも自身で実装する必要があります。
How to customize
Custamazable feature
- アイコン
- アイコン背景の色
- 背景の色
- splash screenの表示時間
- splash screenの終了アニメーション
- ブランディングイメージ
事前準備
Compile SDKを31にする
Jetpack SplashScreenを利用する(2021/10/19
時点では1.0.0-alpha02
が最新)
android {
compileSdkVersion 31
...
}
dependencies {
...
implementation 'androidx.core:core-splashscreen:1.0.0-alpha02'
}
1. splash screenのアイコン
App or Activityに適用されているthemeから以下の様に指定可能。
vector animationなどもOK。
<item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>
Before | After |
---|---|
TBD |
2. アイコン背景の色
App or Activityに適用されるthemeから以下の様にcolor指定可能。
ただしこの設定を適用する場合はthemeのparentをTheme.SplashScreen.IconBackground
にする必要があります。
windowSplashScreenAnimatedIconで設定されたdrawableの背景に対して適用されます。
よって、windowSplashScreenAnimatedIconが指定されていない場合はこの設定は適用されません。
<item name="android:windowSplashScreenIconBackgroundColor">@color/...</item>
Before | After |
---|---|
TBD |
3. 背景の色
App or Activityに適用されるthemeから以下の様にcolor指定可能。
不透明な色でカスタムできます。
<item name="android:windowSplashScreenBackground">@color/...</item>
Before | After |
---|---|
4. splash screenの表示時間
splash screenの表示時間は変更可能です(制限なし)
ただし、Googleの推奨している時間は1000msです。
Before | After |
---|---|
TBD | |
シーンによって以下のやり方があります。 |
アプリを起動にする当たっての準備が済んでいない場合
以下のようにaddOnPreDrawListenerを実装して表示準備が完了した後にOnPreDrawListenerでtrueを返すようにする。
trueが返却されるまではsplash screenが表示されたままになる。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
val content: View = findViewById(android.R.id.content)
content.viewTreeObserver.addOnPreDrawListener(
object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
// Check if the initial data is ready.
return if (viewModel.isReady) {
// The content is ready; start drawing.
content.viewTreeObserver.removeOnPreDrawListener(this)
true
} else {
// The content is not ready; suspend.
false
}
}
}
)
}
splash screenアニメーション終了を待つ場合
アニメーションの終了を待つ場合は、
Activityに適用されるthemeへ以下のように設定します。
この設定値はSplashScreenView.getIconAnimationDuration
で取得ができます。
※ここで設定した時間分splash screenの表示時間が伸びるわけではありません。
<item name="android:windowSplashScreenAnimationDuration">1000</item>
ActivityでSplashScreenにOnExitAnimationListenerを登録し、
SplashScreenViewから取得できるアニメーション開始時刻(animationStart)と上記設定時間(iconAnimationDuration)から残時間を計算し、その分delayさせることでsplash screenの表示時間を適切に伸ばすことができます。
splashScreen.setOnExitAnimationListener { ssv ->
val animationDuration = ssv.iconAnimationDuration
val animationStart = ssv.iconAnimationStart
val remainingDuration = if (animationDuration != null && animationStart != null) {
(animationDuration - Duration.between(animationStart, Instant.now()))
.toMillis()
.coerceAtLeast(0L)
} else {
0L
}
lifecycleScope.launch {
delay(remainingDuration)
ssv.remove()
}
}
5. splash screenの終了アニメーション
以下の様にActivityでSplashScreenにOnExitAnimationListenerを登録し、
SplashScreenView(アイコン)に対してコード上からもAnimationを適用する事ができます。
Before | After |
---|---|
TBD | |
やれることはAndroidのアニメーションに対してできること |
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
// Add a callback that's called when the splash screen is animating to
// the app content.
splashScreen.setOnExitAnimationListener { splashScreenView ->
// Create your custom animation.
val slideUp = ObjectAnimator.ofFloat(
splashScreenView,
View.TRANSLATION_Y,
0f,
-splashScreenView.height.toFloat()
)
slideUp.interpolator = AnticipateInterpolator()
slideUp.duration = 200L
// Call SplashScreenView.remove at the end of your custom animation.
slideUp.doOnEnd { splashScreenView.remove() }
// Run your animation.
slideUp.start()
}
}
6. ブランディングイメージ
App or Activityに適用されるthemeから以下の様に指定可能。
静止画のみ。画面下部に表示される
指定してない場合は何も表示されない。
<item name="android:windowSplashScreenBrandingImage">@drawable/...</item>
Discussion