시배's Android

TiTi Side Project | Theme Color 세팅 본문

Android/TiTi Side Project

TiTi Side Project | Theme Color 세팅

si8ae 2023. 9. 27. 22:19

Compose를 활용한 커스텀 테마 및 다크 모드 / 라이트 모드 대응

Jetpack Compose 사용하면 Android 앱의 사용자 인터페이스를 구축할 커스텀 테마를 설정하고 다크 모드와 라이트 모드 간에 전환하는 기능을 쉽게 구현할 있습니다. 글에서는 커스텀 테마를 설정하고 다크 모드와 라이트 모드를 대응하는 방법을 알아보겠습니다.

커스텀 컬러 팔레트 정의

@Immutable
data class CustomColorsPalette(
    val d1: Color = Color.Unspecified,
    val d2: Color = Color.Unspecified,
    // 다른 컬러들도 포함...
    val clearColor: Color = Color.Unspecified
)

먼저, 앱에서 사용할 커스텀 컬러 팔레트를 정의합니다. 아래 코드는 CustomColorsPalette 데이터 클래스를 사용하여 커스텀 컬러 팔레트를 정의하는 예제입니다. 팔레트에는 라이트 모드와 다크 모드에 대한 컬러가 포함되어 있습니다.

라이트모드, 다크모드 팔레트 정의

val OnLightCustomColorsPalette = CustomColorsPalette(
    d1 = Color(0xFF8299E3),
    d2 = Color(0xFF9AC0DA),
    // 다른 컬러들도 포함...
    clearColor = Color(0x00000000)
)

val OnDarkCustomColorsPalette = CustomColorsPalette(
    d1 = Color(0xFF87A6F8),
    d2 = Color(0xFFA7D7F9),
    // 다른 컬러들도 포함...
    clearColor = Color(0x00000000)
)

라이트모드, 다크모드에 맞게 컬러 값을 설정한 CustomColorsPalette 데이터 클래스를 생성합니다.

CompositionLocal을 사용한 커스텀 테마 적용

커스텀 테마를 Compose 앱에 적용하려면 CompositionLocal 사용합니다. CompositionLocal Composable 함수 내에서 공유되는 값을 저장하고 접근할 사용됩니다. 위의 코드에서는 LocalTiTiColors라는 staticCompositionLocalOf 정의하고 커스텀 컬러 팔레트를 저장합니다.

val LocalTiTiColors = staticCompositionLocalOf {
    CustomColorsPalette()
}

그리고 TiTiTheme이라는 컴포저블 함수를 정의하여 커스텀 테마를 설정합니다. 함수는 다크 모드 또는 라이트 모드에 따라 적절한 컬러 팔레트를 선택하고 CompositionLocalProvider 사용하여 커스텀 컬러 팔레트를 제공합니다.

@Composable
fun TiTiTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit,
) {
    val customColorsPalette =
        if (darkTheme) OnDarkCustomColorsPalette
        else OnLightCustomColorsPalette

    CompositionLocalProvider(
        LocalTiTiColors provides customColorsPalette,
    ) {
        content()
    }
}

또한, TiTiTheme 객체 내의 colors 속성을 사용하여 현재 커스텀 테마의 컬러에 접근할 있습니다.

object TiTiTheme {

    val colors: CustomColorsPalette
        @Composable
        get() = LocalTiTiColors.current

}

TdsColor enum class 구현

enum class TdsColor {
    d1,
    d2,
    // 다른 컬러들도 포함
    clearColor;

    @Composable
    fun getColor() = when (this) {
        d1 -> TiTiTheme.colors.d1
        d2 -> TiTiTheme.colors.d2
        // 다른 컬러들도 포함
        clearColor -> TiTiTheme.colors.clearColor
    }
}

enum class를 정의하여 정의된 컬러 색상만 이용하도록 구현합니다.