Splash Screen(스플래시 화면)은 앱 실행 시 페이지의 컨텐츠가 로딩되기까지 일시적으로 보여주는 화면을 말한다. 주로 로고가 중앙에 박혀있는 화면을 가장 많이 사용한다.
Android 12 이전까지는 개발자가 직접 스플래시 화면을 하나의 액티비티처럼 구현하였으나 Android 12 이상부터는 SplashScreen
API를 이용해서 스플래시 화면을 구성해야한다.
만약 Android 12 이전에서 사용하던 스플래시 화면을 그대로 둔 상태라면 Android 12 이상 기기에서는 해당 앱을 실행할 때, 안드로이드에서 제공하는 기본 스플래시 화면을 먼저 보여준 다음 개발자가 구현한 스플래시 화면을 또 보여주게 된다.
먼저 app
단위 gradle
설정에 SplashScreen
라이브러리를 import 한다.
// SplashScreen
implementation("androidx.core:core-splashscreen:1.1.0-alpha01")
res/values/themes.xml
파일에 Theme.SplashScreen
을 부모로 하는 새로운 theme
을 추가한다.
<style name="Theme.LiamFlix.Starting" parent="Theme.SplashScreen">
<!-- Set the splash screen background, animated icon, and animation duration. -->
<item name="windowSplashScreenBackground">@color/white</item>
<!-- Use windowSplashScreenAnimatedIcon to add either a drawable or an -->
<!-- animated drawable. One of these is required. -->
<item name="android:windowSplashScreenAnimatedIcon">@mipmap/ic_launcher_foreground</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
<!-- Set the theme of the Activity that directly follows your splash screen. -->
<item name="postSplashScreenTheme">@style/Theme.LiamFlix</item>
</style>
android:windowSplashScreenAnimatedIcon
속성에 애니매이션이 적용된 drawable
파일을 추가할 수 있다. 이 예제에서는 애니메이션 효과는 없는 기본 로고로 대신했다. 따라서 android:windowSplashScreenAnimationDuration
속성도 특별한 역할을 하지 않는다.
그 외 SplashScreen
API의 각 속성별 사용 방법은 공식 홈페이지를 참고하자.
위와 같이 theme
를 설정하고 앱을 실행해도 SplashScreen
이 제대로 적용되지 않는 것을 확인할 수 있다.
manifest
에서 런쳐 액티비티의 theme
를 Theme.LiamFlix.Starting
으로 변경해주어야한다.
<activity
android:name=".view.MainActivity"
android:exported="true"
android:theme="@style/Theme.LiamFlix.Starting">
...
</activity>
화면 자체는 성공적으로 구성했지만 지나치게 빨리 사라지는 것을 확인할 수 있다.
스플래시 화면은 앱이 첫 프레임을 그리는 즉시 닫힌다. MainActivity
가 Hello, Android!
표시 외에 다른 실행 구문을 가지고 있지 않기 때문에 빨리 종료되는 것이다.
만약 로컬에서 소량의 데이터를 비동기적으로 로드한다면 런쳐 액티비티에서 ViewTreeObserver.OnPreDrawListener
를 사용하여 첫 프레임을 그릴 앱을 정지할 수 있습니다.
// Create a new event for the activity.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Set the layout for the content view.
setContentView(R.layout.main_activity)
// Set up an OnPreDrawListener to the root view.
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
}
}
}
)
}
추가적으로 런쳐 액티비티에서 SplashScreen
의 종료 애니메이션을 적용할 수 있다.
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()
}
}