본문 바로가기

안드로이드/Compose

[안드로이드 Jetpack Compose] Custom Splash Activity 만들기


이번 포스팅에서는 안드로이드 Jetpack Compose 환경에서 Custom Splash Activity를 만들겠습니다. 그리고 Animatable() 함수를 이용하여 스플래시 화면이 서서히 나타나는 효과를 넣겠습니다. 안드로이드 12 이상부터는 SplashScreen API가 추가됐지만 Custom Splash Activity를 별도로 제작한 이유에 대해서도 설명하겠습니다.

Custom Splash Activity로 구현한 스플래시 화면
Custom Splash Activity로 구현한 스플래시 화면

1. 안드로이드 12 이상에서 제공하는 SplashScreen API의 장단점

해당 기능을 사용하면 별도의 Activity 없이 스플래시 화면을 구성할 수 있기 때문에 리소스와 시간을 절약할 수 있지만 정해진 규격대로만 설정할 수 있어서 디자이너와 기획자의 요구사항에는 부족할 수 있습니다. SplashScreen API의 장단점을 정리하면 아래와 같습니다.

  • SplashScreen API의 장점
    • Activity를 별도로 생성하지 않아도 돼서 시간과 리소스를 절약할 수 있습니다.
    • SplashScreen API를 사용하면 모든 안드로이드 앱과 동일한 경험을 제공해서 일관성을 유지할 수 있습니다.
    • 구글에서 공식적으로 지원하는 기능을 사용하는 것이기 때문에 추후 문제가 발생할 확률이 없습니다.
  • SplashScreen API의 단점
    • SplashScreen을 사용하면 화면 가운데에 이미지 한 개와 백그라운드만 설정할 수 있습니다.
    • 이로 인해 디자이너와 기획자의 스플래시 화면에 대한 자유도가 떨어집니다.
    • 마음대로 커스텀하기 어렵습니다.

2. Custom Splash Activity를 만든 이유

제가 진행한 프로젝트는 스플래시 화면에서 간단하게 서버와 통신하는 기능이 있었고, 화면 가운데와 하단에 이미지를 배치하는 형태로 개발을 해야 해서 SplashScreen API를 사용하지 않고, Custom Splash Activity로 제작하게 되었습니다.

3. Custom Splash Activity 적용하기

  1. Custom Splash Activity를 만듭니다.
  2. 안드로이드 기본 SplashScreen에 나타나는 배경색과 이미지를 없애기 위해 themes.xml에 style을 생성합니다.
  3. AndroidManifest.xml에 Custom Splash Activity를 추가하고 style을 적용해 줍니다.

위의 과정을 순서대로 예제 코드와 함께 설명하겠습니다.

3-1. Custom Splash Activity 만들기

다음은 Splash Activity 소스코드입니다. 해당 화면에서 구현한 기능은 다음과 같습니다.

  • Animatable() 함수를 사용하여 1.5초 동안 alpha 값이 0부터 1까지 증가하게 하고, 각 이미지의 alpha 속성에 적용하여 스플래시 화면에 진입했을 때 이미지가 서서히 나타나는 효과를 적용했습니다.
  • LaunchedEffect 컴포저블 내부에서 startActivity() 함수를 사용하여 애니메이션이 끝난 후 MainActivity로 이동하는 기능을 넣었습니다.
@SuppressLint("CustomSplashScreen")
@AndroidEntryPoint
class SplashActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            // val viewModel = hiltViewModel<SplashViewModel>() // viewmodel 필요한 경우 사용
            CleanarchitectureexampleTheme {

                StatusBarColor(barColor = Mint40)

                SplashScreen()
            }
        }
    }

    @Preview
    @Composable
    fun SplashScreen(

    ) {
        val alpha = remember {
            Animatable(0f)
        }
        LaunchedEffect(key1 = Unit) {
            alpha.animateTo(
                targetValue = 1f,
                animationSpec = tween(1500)
            )
            delay(2000L)

            Intent(this@SplashActivity, MainActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            }.let { intent ->
                startActivity(intent)
            }
        }

        Column(
            modifier = Modifier
                .fillMaxSize()
                .background(Mint40),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {

            val painter = painterResource(R.drawable.splash_screen_logo)

            Column(
                modifier = Modifier.weight(1f),
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Center
            ) {
                Image(
                    modifier = Modifier
                        .width(200.dp)
                        .height(93.dp)
                        .alpha(alpha.value),
                    painter = painter,
                    contentDescription = "Welluga Staff",
                )
            }

            Image(
                modifier = Modifier
                    .fillMaxWidth()
                    .alpha(alpha.value),
                painter = painterResource(id = R.drawable.splash_screen_bottom),
                contentScale = ContentScale.FillWidth,
                contentDescription = "Welluga Staff"
            )
        }
    }
}

3-2. themes.xml에 Splash Activity 전용 style 만들기

안드로이드 12 이상에서 제공해 주는 SplashScreen에 나타나는 이미지를 없애고, 위에서 만든 Custom Splash Activity의 배경색과 동일하게 설정해 줍니다. 왜냐하면 앱을 실행했을 때 어색하지 않게 Custom Splash Activity가 나오게 해야 하기 때문입니다.

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

    <style name="Theme.Cleanarchitectureexample" parent="android:Theme.Material.Light.NoActionBar" />

    <!-- 스플래시 스크린 설정 -->
    <style name="Theme.MySplashScreen" parent="Theme.Cleanarchitectureexample">
        <item name="android:windowBackground">@color/mint_40</item>
        <item name="android:windowSplashScreenAnimatedIcon" tools:targetApi="s">@color/mint_40</item>
    </style>

</resources>

3-3. AndroidManifest.xml 파일 설정하기

위에서 만든 SplashActivity를 시작 화면으로 설정하고 style을 적용하기 위해서 AndroidManifest.xml 파일을 다음과 같이 수정했습니다.

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

    <application
        ... >
        
        <activity
            android:name=".view.splash.SplashActivity"
            android:theme="@style/Theme.MySplashScreen"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".view.main.MainActivity"
            android:exported="true">
        </activity>
    </application>
</manifest>

4. 결론

  • 안드로이드에서 제공하는 SplashScreen API는 사용이 간편하고 일관된 사용자 경험을 제공
  • Custom Splash Activity는 디자이너와 기획자의 요구사항을 충족시키고 더 많은 자유도와 유연성을 가짐

이번 포스팅에서는 Custom Splash Activity를 구현하는 과정에 대해 설명했지만, 여러분의 프로젝트 요구사항에 따라 SplashScreen API, Custom Splash Activity 중에서 적합한 방법을 선택하면 좋을 것 같습니다.