[Android] 안드로이드 12 Splash Screen 적용하기

박주호·2022년 2월 17일
5

Hi, Android

목록 보기
5/7
post-thumbnail

Splash Screen이란

기존에 작성한 Splash Screen적용하기를 참고해주세요!

🛠 안드로이드 12 출시

한국시간으로 21년 10월 5일, 안드로이드 12가 출시되었습니다.
여러 변경점이 있었지만 그중에서도 앱을 시작하는 Spalsh Screen이 자동으로 생성되는 기능이 생겼습니다.
개발자가 아무 설정을 하지 않아도 앱 아이콘이 스플래쉬 테마로 적용이 된 것입니다!

... 이렇게 행복하게 살았다면 좋았겠지만 문제가 있었습니다.

Splash Screen을 적용해야하는 이유

1. SDK에 따른 UI 불일치

아무 작업도 해놓지 않았던 앱의 경우, 시작 화면을 구현했지만 앱아이콘이 아닌 다른 이미지를 적용해 놓은 경우
안드로이드 12와 그 이하 버전에서 시작화면이 다른 결과가 생깁니다.

2. Splash Activity와 중복

시작화면을 설정하는 방법은 여러가지로 그중에 하나는 시작 화면을 액티비티로 설정해두고 메인화면으로 이동하는 것입니다.
저는 시작화면을 따로 액티비티로 두지않아 2번 문제엔 문제가 없었으나
타 앱을 이용해보았을 때 안드로이드 12의 경우 앱 아이콘이 뜨면서
기존의 시작화면까지 뜨며 UI / UX적으로 좋지않은 경험을 하였습니다.

3. 저장소로부터 데이터를 불러오기

2번 문제를 해결하기 위해 액티비티를 제거하고 기본 앱 아이콘을 시작화면으로 쓸 수 있다.
하지만 시작화면 시 저장소로부터 데이터를 불러와 준비가 끝나면 메인화면으로 이동하는 앱이라면?
데이터를 불러와 준비가 될 때까지 시작화면을 유지하는 로직을 구현해야한다.

이러한 이유로 Android 12에 맞추어 Splash Screen을 적용하게 되었습니다.
또한 이번 기회에 더 좋은 경험을 느끼게 하고싶어 애니메이션 아이콘을 사용하였습니다.

👀 미리보기

기본


종료 애니메이션 추가


실제 적용


코드는 GitHub Sample 를 참고해주세요.

🔥 적용하기

준비사항

  1. Android 12 버전의 테스트 기기 (혹은 에뮬레이터)
  2. Animated Vector Drawable

2번 준비물에 대한 과정은
Animated Vector Drawable 만들기 를 참고해주세요.
자세한 과정은.. 혹시 궁금하신점이 있으면 댓글 남겨주세요 최대한 알려드리겠습니다!

이 과정이 귀찮으신분들은 아래에 제가 만들어 놓은 샘플을 이용해주시면 됩니다. (하트한번 눌러주시면 감사하겠습니다! 찡-긋😉)

샘플 Animated Vector Drawable 완성본 다운로드

과정

라이브러리 추가 -> drawble 폴더에 Animated Vector Drawable 추가 -> themes.xml 수정 -> (필요 시) viewTreeObserver 리스너 추가

📌 라이브러리 추가

implementation("androidx.core:core-splashscreen:1.0.0-beta01")

📌 drawble 폴더에 Animated Vector Drawable 추가

📌 themes.xml 수정

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">

    <style name="Theme.Test" parent="Theme.MaterialComponents.Light.NoActionBar">
    	...
        <!-- Customize your theme here. -->
        <item name="android:windowSplashScreenBackground">@color/white</item>
        <item name="android:windowSplashScreenAnimatedIcon">@drawable/avd_anim</item>
        <item name="android:windowSplashScreenAnimationDuration">500</item>
        ...
    </style>
</resources>

공식문서에서는 다음과 같이 아이콘이 구성된다고 설명하고 있습니다.

1️⃣ 앱 아이콘은 Vector Drawble이어야 하며 정적이거나 애니메이션일 수 있습니다. 애니메이션은 1초를 초과하지 않는것이 좋습니다.
2️⃣ (옵션) 아이콘과 배경의 대비가 필요한 경우 유용합니다. 적응형 아이콘을 사용해 배경과 대비가 충분하면 배경이 표시됩니다.
3️⃣ 배경의 1/3이 가려집니다.
4️⃣ 배경은 단일 색상으로 구성됩니다. 속성이 설정되어있지않다면 기본적으로 사용됩니다.

저는 배경은 흰색에 avd_anim파일을 애니메이션 아이콘으로 설정하였습니다.
이때 windowSplashScreenAnimationDuration 옵션은 시작 화면이 표시되는 실제 시간에 영향을 끼치지 않지만
종료 화면 애니메이션을 커스텀할 때 영향을 끼칩니다.
(최소 시간 혹은 특정 작업동안 Splash 화면이 유지되려면 viewTreeObserver 리스너를 이용해주어야 합니다.)

📌 (필요 시) viewTreeObserver 리스너 추가

// 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
                }
            }
        }
    )
}

false 반환 시 뷰가 그려지는게 중단되며
true 반환 시 뷰가 그려지기 시작하며 활동이 시작됩니다.

저장소에서 데이터를 불러오거나 특정 작업이후에 뷰를 그려야할 경우 사용해주시면 됩니다.

추가

시작 화면이 종료를 커스텀하고 싶다면

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()
    }
}

와 같이 코드를 추가하여 종료 애니메이션을 커스텀 해줄 수 있습니다.

공식문서에 아이콘 사이즈와 더 많은 유의사항이 있으니 한번 읽어보시길 추천합니다!

참고

Android12's Splash Screen API
Android Developers - Splash Screen

profile
항상 배우려는 자세로

1개의 댓글

comment-user-thumbnail
2022년 11월 14일

감사합니다. 잘 읽었습니다~

답글 달기