본문 바로가기
Programando/Android

[Android/Kotlin] 안드로이드 12 SplashScreen 대응하기

SplashScreen API는 안드로이드 12 이상 기기에서 실행할 때 모든 앱에서 새로운 런칭 애니메이션을 사용할 수 있도록 합니다. 여기에는 시작 시 앱 내 동작, 앱 아이콘을 보여주는 스플래시 화면, 앱 자체로의 전환 등이 포함됩니다.

 

SplashScreen 기본적인 사용법

0. 종속성 추가

SplashScreen API는 모든 안드로이드 12 이상의 기기에서 적용되는데, Android 11 이하에서 사용자 지정 스플래시 화면을 구현한 적이 있는 경우 앱을 SplashScreen API로 마이그레이션하여 Android 12 이상에서 올바르게 표시되도록 해야 합니다.

Androidx SplashScreen 호환 라이브러리를 사용하면 모든 안드로이드 버전에 걸쳐 일관된 스플래시 화면을 표시할 수 있습니다. 그러기 위해 app 모듈의 build.gradle에서 종속성을 추가합니다.

dependencies {
    ...
    implementation 'androidx.core:core-splashscreen:1.0.0-rc01'
}

 

1. Theme 추가

새로운 테마를 만들고, 해당 테마의 parent를 Theme.SplashScreen 혹은 Theme.SplashScreen.IconBackground로 설정합니다.

테마 내에 들어갈 속성들은 Customize the splash screen in your app , Migrate your splash screen implementation 을 참고하시면 됩니다.

    <style name="Theme.App.Starting" parent="Theme.SplashScreen">
        <!-- Android Version 12 이상, SplashScreen -->
        <item name="android:windowSplashScreenBackground" tools:targetApi="S">@color/white</item>
        <item name="android:windowSplashScreenAnimatedIcon" tools:targetApi="S">@drawable/ic_launcher_foreground</item>
        <item name="android:windowSplashScreenIconBackgroundColor" tools:targetApi="S">@color/purple_200</item>
        <!-- Android Version 12 미만, SplashScreen -->
        <item name="windowSplashScreenBackground">@color/white</item>
        <item name="windowSplashScreenAnimatedIcon">@drawable/ic_launcher_foreground</item>
        <item name="windowSplashScreenIconBackgroundColor">@color/purple_200</item>
        <!-- SplashScreen 이후의 화면 Theme 설정 -->
        <item name="postSplashScreenTheme">@style/Theme.App</item>
    </style>

 

2. Manifest 설정

<application> 혹은 시작 <activity>에 새로 만든 테마를 적용해줍니다.

<manifest>
   <application android:theme="@style/Theme.App.Starting">
    <!-- or -->
        <activity android:theme="@style/Theme.App.Starting">
...

 

3. installSplashScreen() 호출

onCreate() 메서드에서 super.onCreate(savedInstanceState)를 호출하기 직전에 installSplashScreen()을 호출해줍니다.

class MainActivity : Activity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       // Handle the splash screen transition.
       installSplashScreen()

       super.onCreate(savedInstanceState)
       setContentView(R.layout.main_activity)
...

installSplashScreen()은 스플래시 화면 개체를 반환하며, 이 개체를 사용하여 애니메이션을 커스텀하거나 스플래시 화면을 장시간 화면에 유지할 수 있습니다.

 

SplashScreen Custom 하는 방법

- SplashScreen 화면에 장시간 유지

SplashScreen은 앱이 첫 번째 프레임을 그리는 즉시 해제됩니다. 만약 조금 더 오래 스플래시를 잡아둘 필요가 있는 경우에는 ViewTreeObserver.OnPreDrawListener를 통해 앱이 첫 번째 프레임을 그리는 것을 일시 중단할 수 있습니다.

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        val content: View = findViewById(android.R.id.content)
        content.viewTreeObserver.addOnPreDrawListener(
            object : ViewTreeObserver.OnPreDrawListener {
                override fun onPreDraw(): Boolean {
                    return if (isHideSplash) {
                        // The content is ready; start drawing.
                        content.viewTreeObserver.removeOnPreDrawListener(this)
                        true
                    } else {
                        // The content is not ready; suspend.
                        false
                    }
                }
            }
        )
        ...
    }

 

- SplashScreen 애니메이션

Activity.getSplashScreen()을 통해 SplashScreen의 애니메이션을 커스터마이징할 수 있습니다. Activity.getSplashScreen()의 경우, API 31 이상에서만 사용할 수 있으므로 31 미만 버전에서는 SplashScreenViewProvider.view를 통해 접근할 수 있습니다.

class MainActivity : Activity() {

   // SplashScreen
   private lateinit var installSplashScreen: SplashScreen

   override fun onCreate(savedInstanceState: Bundle?) {
       // Handle the splash screen transition.
       installSplashScreen = installSplashScreen()
       
       splashScreenAnimation()
   }

    private fun splashScreenAnimation() {
        // SplashScreen 이 사라질 때 애니메이션 효과
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            splashScreen.setOnExitAnimationListener { splashScreenView ->
                val fadeOut = ObjectAnimator.ofFloat(
                    splashScreenView,
                    "alpha",
                    1.0f,
                    0.0f
                )
                fadeOut.interpolator = AnticipateInterpolator()
                fadeOut.duration = 1000L

                // custom animation 이 끝난 후 SplashScreenView.remove() 호출
                fadeOut.doOnEnd { splashScreenView.remove() }

                fadeOut.start()
            }
        } else {
            installSplashScreen.setOnExitAnimationListener { splashScreenView ->
                val fadeOut = ObjectAnimator.ofFloat(
                    splashScreenView,
                    "alpha",
                    1.0f,
                    0.0f
                )

                fadeOut.interpolator = AnticipateInterpolator()
                fadeOut.duration = 1000L

                // custom animation 이 끝난 후 SplashScreen 제거
                fadeOut.doOnEnd { splashScreenView.remove() }

                fadeOut.start()
            }
        }
    }
}

 

완성된 화면

 

그 외

자료 참조

https://developer.android.com/guide/topics/ui/splash-screen/migrate

https://developer.android.com/guide/topics/ui/splash-screen

반응형