Androidのスプラッシュスクリーンの決定的なガイド


スプラッシュ画面は、起動画面と呼ばれる、画面のアプリとしては、アプリケーションの起動時に負荷として表示されます.彼らは瞬間的なブランドの露出を提供したり、ユーザーの経験を向上させるアプリのプレビューを示すことによって開始すると、ユーザーの認識負荷時間を減らすことができます.

ブランドとプレビュースプラッシュ画面Material Design docs
私が取り組んできた多くのプロジェクトでは、スプラッシュ画面を表示するに加えて、我々はスプラッシュと最初のアプリケーション画面の間の移行をアニメーション化していた.アニメーションの種類に応じて、どのように我々は最初のアプリケーションのビューを示している、我々はアニメーションの間にジャンクまたは認識可能な遅延を持つことができます.したがって、ユースケースに適切なアプローチを選択する必要があります.
この記事では、どのようにアニメーションのスプラッシュ画面がAndroidで作成され、どのようにこれを行う必要があります今私たちが持っているJetpack's Core SplashScreen , アンドロイド・マシュマロ(API 23)に戻るアンドロイド12スプラッシュスクリーンAPIをバックアップします.
Androidアプリの次のブランドスプラッシュ画面を実装しなければならないとしましょう
Click to see the design on Figma
我々はブランドイメージを開始し、それをフェードアウトし、開始画面での移行を開始します.このユースケースは、デザインの単純なトランジションを持っているにもかかわらず、スプラッシュスクリーンディスプレイで複数のテクニックを行使します.アニメーションは連続的に実行しなければならず、それらの間の長い遅延またはジャンクは許容できません.

単純なもの


簡単に起動しましょう:あなたがスプラッシュ画面を設定しないときにAndroidで何が起こるかを示す.作成後'Empty Activity Project' Android Studioでは、メイン画面のレイアウトを開始画面の参照と同じデザインを持って調整されました.何もスプラッシュ画面について行われた.
このようにしてAPIレベル30に表示されます.
我々はまだスプラッシュ画面を設定する何も追加しなかったとして、メイン画面が読み込まれている間、黒い画面が表示されます.
重要:Androidの12では、静的なブランドのスプラッシュ画面が自動的にすべての努力なしで中心のアプリのアイコンを使用して表示されました.良い改善!

Androidの12の自動静的スプラッシュ画面

この手順を繰り返すには、GithubのRepoで次のブランチをクローンします.github.com/tgloureiro/animated_splashscreen_android/tree/step1_no_splash

スプラッシュスクリーン(古い方法)を示す


Androidでスプラッシュスクリーンを定義する伝統的な方法は、起動されているアクティビティにウィンドウの背景を設定します.コンテンツがまだ接続されていないので、アクティビティが読み込まれている間にウィンドウの背景が完全に表示されます.読み込まれた後、コンテンツビューはonCreate() メソッドのビューが開始されます.
したがって、スプラッシュ画面を表示するには、アクティビティによって使用されるテーマのウィンドウの背景を設定します.
/res/values/themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.AnimatedSplashScreen" 
        parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <!-- Drawable to be rendered in window's background 
             while the activity is being loaded -->
        <item name="android:windowBackground">
            @drawable/your_splashscreen_drawable
        </item>
    </style>
</resources>
我々はいくつかの背景のドロウアブルを中心にロゴを中心にスプラッシュ画面が必要な場合は、我々は使用することができますLayerDrawable , これにより、宣言した順序で描画されるドロウアブルのリストを指定することができます.この例では、ロゴが画面に集中するフラットカラーの背景があります.の使用android:gravity プラットフォームにスクリーンの中央に2番目のドロウアブルをセンターに知らせます.
/res/drawable/splash_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/splash_background"/>
    <item android:gravity="center" 
        android:drawable="@drawable/splash_logo" />
</layer-list>
スプラッシュの背景には、任意のタイプのdrawableを使用することができます.この例では、ソリッドカラーを使用します.ここでしたように、別のドロウアブルを指し示すのではなく、レイヤーリスト内で直接色を指定することができます
/res/drawable/splash_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/blue" />
</shape>
これは、スプラッシュスクリーンを行う古い方法であり、APIのレベル22、新しいコアスプラッシュ画面APIで覆われていないものまでお勧めします.

ロゴをフェードアウト


スプラッシュスクリーンのフェードアウトを実行した後に実装する簡単な方法があります:我々は、ロゴなしでスプラッシュ画面と画面の背景の間のクロスフェードアウトのロゴフェードアウトの幻想を持つことができます.我々はそれを使用することができますTransitionDrawable . 遷移Drawableは2つのdrawableな層を定義して、容易にそれらの間でフェードを交差させますstartTransition(int) メソッド.
/res/drawable/splash_transition.xml
<?xml version="1.0" encoding="utf-8"?>
<transition 
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/splash_screen" />
    <item android:drawable="@drawable/splash_background" />
</transition>
次のタスクを実行しなければなりません.
  • スプラッシュ画面が表示されない場合はチェックします
  • ウィンドウの背景への参照を取得し、クロスフェード遷移を開始する
  • コルーチンを起動し、アニメーションの継続時間を待った後、コンテンツビューを設定します
  • MainActivity.kt
    class MainActivity : AppCompatActivity() {
      ...
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          // Checks if the splash screen was displayed before
          // ->SavedInstanceState is not null after recreation!
          val splashWasDisplayed = savedInstanceState != null
          if(!splashWasDisplayed){
              // 1 - Start fading out the logo
              (window.decorView.background 
                  as TransitionDrawable).startTransition(
                      logoCrossFadeDurationMillis
                  )
              // 2 = As we can't register a listener to be 
              // notified when the transition drawable finishes,
              // launches a coroutine that blocks while animation
              // is being performed and sets the content view
              lifecycleScope.launch {
                  // Time between the animations
                  delay(logoCrossFadeDurationMillis.toLong()
                    + spacingAfterFadeDurationMillis)
                  window.decorView.background = 
                    AppCompatResources.getDrawable(
                        this@MainActivity,
                        R.drawable.splash_background
                    )
                  setContentView(R.layout.activity_main)
              }
          }else{
              // Splash was shown before, no need to animate it.
              // 1 - Updates the window background (if needed)
              window.decorView.background = 
                AppCompatResources.getDrawable(
                  this,R.drawable.splash_background
                )
              // 2 - Sets the content view instantly
              setContentView(R.layout.activity_main)
          }
      }
      ...
    
    電話でレンダリングされる方法を確認します

    この手順を繰り返すには、GithubのRepoで次のブランチをクローンします.github.com/tgloureiro/animated_splashscreen_android/tree/step2_fade_out_splash

    スプラッシュスクリーンを示す


    コアスプラッシュ画面APIは、スプラッシュ画面にある要素を定義する方法を提供します.スプラッシュ画面を設定するには、次の手順を実行する必要があります.
    1 -設定のスタイルを設定します.テーマとして親として* Splashscreen.XML
    themes.xml
        ...
        <style name="Theme.AppSplash" parent="Theme.SplashScreen">
    
        </style>
    
    2 -設定WindowSplashScreenBackground , WindowSplashScreenAnimateDiconとしての背景と中央のロゴ
    themes.xml
        ...
        <style name="Theme.AppSplash" parent="Theme.SplashScreen">
            <item name="windowSplashScreenBackground">@drawable/your_background_drawable</item>
            <item name="windowSplashScreenAnimatedIcon">@drawable/your_icon_drawable</item>
        </style>
    
    3 -セットアップテーマは、スプラッシュ画面の後に活動に表示される
    themes.xml
        ...
        <style name="Theme.AppSplash" parent="Theme.SplashScreen">
            <item name="windowSplashScreenBackground">@drawable/your_background_drawable</item>
            <item name="windowSplashScreenAnimatedIcon">@drawable/your_icon_drawable</item>
            <item name="postSplashScreenTheme">@style/your_activity_theme</item>
        </style>
    
    4 -ビルドで.Gradleを使用して、コンパイラのバージョンを「アンドロイドS」に変更します(Android 12のリリースでapilevel 31に変更されます).
    build.gradle
    
    ...
    android {
        compileSdkVersion "android-S"
        ...
    }
    ...
    dependencies {
        ...
        implementation 'androidx.core:core-splashscreen:1.0.0-alpha01'
    }
    
    5 -最後に、メインアクティビティ(またはあなたのアプリケーションのエントリポイント)では、単にコールする必要がありますてinstallSplashScreen() 以前setContentView()
    MainActivity.kt
    ...
     override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            installSplashScreen()
            setContentView(R.layout.activity_main)
        }
    }
    
    非常に簡単な、huh?これらの簡単な手順を使用すると、API 23からAndroid 12にスプラッシュ画面を表示されます.

    コアスプラッシュスクリーンAPI


    Android 12では、ロゴ自体をアニメーション化することができますAnimationDrawable or AnimatedVector . The AnimationDrawable あなたが表現しなければならない古典的なアニメーションに似た作品
    フレームごとにフレームと期間.AnimatedVectorDrawable フレームワークによって補間されるアニメーションについて説明しましょう.
    コアスプラッシュスクリーンAPIのバックポート版はまだロゴのアニメーションをサポートしていません.しかし、我々はSplashの展覧会の後にfadeoutアニメーションを実装することができますし、このAPIを使用してそれを実装する方法を示します.
    次のタスクを実行しなければなりません.
  • スプラッシュ画面が表示されていない場合は、それ以外の場合は、手動でテーマとコンテンツビューを設定
  • スプラッシュスクリーンをインストールし
  • ロゴへの参照を取得し、それをフェードアウト、スプラッシュを削除し、それが終了した後にコンテンツビューを設定して
  • MainActivity.kt
    class MainActivity : AppCompatActivity() {
        companion object{
            const val splashFadeDurationMillis = 300
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val splashWasDisplayed = savedInstanceState != null
            if(!splashWasDisplayed){
                val splashScreen = installSplashScreen()
                splashScreen.setOnExitAnimationListener { 
                    splashScreenViewProvider ->
                    // Get logo and start a fade out animation
                    splashScreenViewProvider.iconView
                        .animate()
                        .setDuration(
                            splashFadeDurationMillis.toLong()
                        )
                        .alpha(0f)
                        .withEndAction {
                            // After the fade out, remove the 
                            // splash and set content view
                            splashScreenViewProvider.remove()
                            setContentView(R.layout.activity_main)
                        }.start()
                }
            }else{
                setTheme(R.style.Theme_AnimatedSplashScreen)
                setContentView(R.layout.activity_main)
            }
        }
    }
    
    電話でレンダリングされる方法を確認します

    この手順を繰り返すには、GithubのRepoで次のブランチをクローンします.github.com/tgloureiro/animated_splashscreen_android/tree/step3_core_splash_api_fade_out

    Jetpackを使用したコアスプラッシュスクリーンAPIを使用したスプラッシュスクリーンの表示


    スプラッシュ・ステップは、私たちがComposesetContent{} の代わりにsetContentView(int) . それです.
    ここでの課題は、MotionLayoutを使用して作成したスタートスクリーンアニメーションを置き換えるためのものです.最初に目に見えないanimatedVisible ableを使用して、Launchedeffectを使用して最初のパスに表示できます.可視化すると、ウィジェットで説明されているアニメーションを開始します.
    MainActivity.kt
    fun StartScreen() {
        var visible by remember { mutableStateOf(false) }
    
        Scaffold(
            content = {
                Box(
                    modifier = Modifier
                        .background(
                            colorResource(id = R.color.blue)
                        )
                        .fillMaxSize(),
                ) {
                    AnimatedVisibility(
                        visible = visible,
                        enter = slideInVertically(
                            initialOffsetY = {
                                // Slide in from top
                                -it
                            },
                            animationSpec = tween(
                              durationMillis = 
                              MainActivity.splashFadeDurationMillis,
                            easing = LinearEasing
                        )
                        ),
                    ) {
                        Column(
                            verticalArrangement = 
                                Arrangement.Center,
                            horizontalAlignment = 
                                Alignment.CenterHorizontally,
                            modifier = Modifier
                                .padding(
                                    0.dp, 
                                    0.dp, 
                                    0.dp,
                                    0.dp
                                )
                                .background(
                                    colorResource(
                                        id = R.color.blue
                                    )
                                )
                                .fillMaxSize()
                        ) {
                            Text(
                                stringResource(
                                    id = R.string.start_screen_title
                                ),
                                fontSize = 36.sp,
                                modifier = Modifier.padding(
                                    bottom = 
                                    dimensionResource(
                                        R.dimen.start_content_title_margin_bottom
                                        )
                                    ),
                                color = Color.White,
                                fontWeight = FontWeight.Bold
                            )
                            Box(
                                modifier = Modifier
                                    .height(
                                        dimensionResource(
                                            R.dimen.start_content_size
                                            )
                                        )
                                    .width(dimensionResource(
                                        R.dimen.start_content_size
                                        )
                                    )
                                    .clip(
                                        RoundedCornerShape(
                                            8.dp
                                        )
                                    )
                                    .background(color = Color.White)
                            )
                        }
                    }
                }
                LaunchedEffect(true) {
                    visible = true
                }
            }
        )
    }
    
    電話でレンダリングされる方法を確認します

    この手順を繰り返すには、GithubのRepoで次のブランチをクローンします.github.com/tgloureiro/animated_splashscreen_android/tree/step4_core_splash_jetpack

    最後の思考


    新しいJetpackコアのSplashScreen APIは、API 23に戻ってスプラッシュスクリーンを作成するためのデフォルトの方法を提供します.結果は、我々が以前に持っていたものと類似しています.そして、減少したボイラー板と新しいAndroidバージョンとの互換性の利益を得ました.