안드로이드 기존 앱에 컴포즈 부분 적용 (Splash Screen)

컴포즈를 적용하고 싶다

안드로이드 스튜디오의 가이드를 보면 컴포즈 UI 의 부분 적용이 가능하다

기존의 Splash Screen 을 Compose 로 변환해보자

Splash 를 Compose 로 변환하면 안됩니다
Splash API 를 사용할 께 아니면 변환하지 마세요.
이유는 Compose UI 의 컨셉이 하나의 Activity 안에서 여러 개의 스크린이 움직이는
SPA (Single Page Application) 을 권장합니다.
Compose navigation 으로 navigation 구현하면서 더 Splash Screen 이 문제되네요.

Splash Activity - > Main Activity -> Compose UI 구현 이게 맞는 것 같습니다

기존 앱에 Compose 설정

앱의 build.gradle 에 설정 추가

컴포즈 옵션의 버전은 컴포즈 호환성 표 여기서 확인이 가능합니다.
코틀린 1.7.20 버전을 사용하니 1.3.2 를 적용합니다

1
2
3
4
5
6
7
8
9
android {
buildFeatures {
compose true
}

composeOptions {
kotlinCompilerExtensionVersion = "1.3.2"
}
}

build.gradle 에 설정 추가

navigation compose 2.5.3 버전을 추가합니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
dependencies {
...

// compose
def composeBom = platform('androidx.compose:compose-bom:2022.10.00')
implementation composeBom
androidTestImplementation composeBom

// Choose one of the following:
// Material Design 3
implementation 'androidx.compose.material3:material3'
// or only import the main APIs for the underlying toolkit systems,
// such as input and measurement/layout
implementation 'androidx.compose.ui:ui'
// Android Studio Preview support
implementation 'androidx.compose.ui:ui-tooling-preview'
debugImplementation 'androidx.compose.ui:ui-tooling'

// compose navigation
implementation "androidx.navigation:navigation-compose:$rootProject.navigationVersion"

...

build.gradle Project

1
2
3
4
5
6
7
8
9
ext {
coreVersion = '1.9.0'
roomVersion = '2.4.3'
appCompatVersion = '1.5.1'
coroutines = '1.6.1'

composeVersion = '1.3.2'
navigationVersion = '2.5.3'
}

테마생성

Splash Screen 에서 사용할 테마를 생성합니다
themes.xml 에 테마 추가합니다

1
2
3
4
5
<style name="Theme.SplashScreen" parent="android:Theme.Material.Light.NoActionBar">
<item name="android:statusBarColor">@color/black</item>
<item name="android:windowBackground">@color/black</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/all_transparent</item>
</style>

투명한 이미지도 drawable 에 추가합니다
all_transparent.xml

1
2
<?xml version="1.0" encoding="utf-8"?>
<shape/>

Splash Screen 을 Compose 로 만들기

SplashScreen.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.skyksit.dsam3.screen

import android.os.Handler
import android.os.Looper
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.skyksit.dsam3.R
import com.skyksit.dsam3.navigation.Screen

@Composable
fun SplashScreen(navController: NavController) {
drawLogo()

Handler(Looper.getMainLooper()).postDelayed({
navController.navigate(Screen.GameList.route)
}, 2000)
}

@Preview
@Composable
fun drawLogo() {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Black)
) {
Column(
Modifier
.padding(vertical = 50.dp)
.fillMaxWidth()
.fillMaxHeight(),
verticalArrangement = Arrangement.SpaceAround,
horizontalAlignment = Alignment.CenterHorizontally
) {
val logo: Painter = painterResource(id = R.drawable.all_logo)
val appname: Painter = painterResource(id = R.drawable.all_appname)
Image(
painter = logo,
contentDescription = "logo",
modifier = Modifier.size(150.dp)
)
Image(
painter = appname,
contentDescription = "dos game player",
modifier = Modifier.size(200.dp)
)
}
}
}

결론

Splash 를 Compose 로 변환하면 안됩니다
Splash API 를 사용할 께 아니면 변환하지 마세요.
이유는 Compose UI 의 컨셉이 하나의 Activity 안에서 여러 개의 스크린이 움직이는
SPA (Single Page Application) 을 권장합니다.
Compose navigation 으로 navigation 구현하면서 더 Splash Screen 이 문제되네요.

Splash Activity - > Main Activity -> Compose UI 구현 이게 맞는 것 같습니다