[Compose] Splash Screen 및 초기 데이터 로딩

Compose로 개발 중 Splash Screen을 사용할 일이 생겼다.

 

적용을 하기위해 두가지 필요성이 있었는데 다음과 같다.

1. 최신 안드로이드 기기에서 사용

2. Splash Screen은 데이터 로딩 후 종료되어야함

 

먼저 스플래쉬 스크린을 사용하기 위해 build.gradle에 추가한다.

implementation 'androidx.core:core-splashscreen:1.0.1'

 

이제 splash screen의 기본적인 설정을 적용해줄 테마를 만든다.

<style name="Theme.Convenii.Starting" parent="Theme.SplashScreen">
    <item name="windowSplashScreenAnimatedIcon">@mipmap/splash_main</item>
    <item name="windowSplashScreenBackground">@color/white</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowActionBar">false</item>
</style>

해당 테마로 스플래쉬 스크린의 배경, 아이콘등을 설정할 수 있다.

 

이제 적용을 위해 manifest를 수정하였다.

<application
    android:name=".MainApplication"
    android:usesCleartextTraffic="true"
    android:allowBackup="true"
    android:dataExtractionRules="@xml/data_extraction_rules"
    android:fullBackupContent="@xml/backup_rules"
    android:icon="@mipmap/splash_main"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/splash_main"
    android:supportsRtl="true"
    android:theme="@style/Theme.Convenii.Starting"
    tools:targetApi="31">
    <activity
        android:name=".MainActivity"
        android:windowSoftInputMode="adjustResize"
        android:exported="true"
        android:label="@string/app_name"
        android:theme="@style/Theme.Convenii.Starting">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

applicaton단과 activity단의 theme를 바꿔주었다.

 

하지만 이렇게 적용할 시 dialog창이 아래에 고정돼버리는 버그가 발생하였다.

이를 해결해주기 위해 theme파일에 다음과 같은 코드를 추가하였다.

<item name="postSplashScreenTheme">@style/Theme.Convenii</item>

해당 구문은 스플래쉬 스크린 이후 적용할 테마를 선택할 수 있게 해준다.

따라서 Theme.convenii를 스플래시 스크린 이후에 적용시키게 된다.

 

이제 activity단에서 splashscreen을 적용시킨다.

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    private val viewModel: SplashViewModel by viewModels()

    @SuppressLint("StateFlowValueCalledInComposition")
    @RequiresApi(Build.VERSION_CODES.S)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)


        val splashScreen = installSplashScreen()
        splashScreen.setKeepOnScreenCondition {
            !viewModel.isReady.value
        }

        setContent {
            val startDestination by viewModel.screen.collectAsState()
            ConveniiTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    color = Color.White,
                ) {
                    if (startDestination.isNotEmpty()) {
                        ConveniiApp(startDestination)
                    }
                }
            }
        }
    }
}

installSplashScreen을 사용해 스플래시 스크린을 적용시키고

setKeepOnSCreenCondition을 사용해 데이터가 로딩될 때 까지 유지시켰다.