지금까지는 컴포저블 함수에 어떠한 스타일도 적용하지 않았고, 다크모드 지원을 포함하는 적당한 기본값으로만 코드를 작성했다. BasicsCodelabTheme과 MaterialTheme을 내부를 살펴보자.

ui/Theme.kt 파일을 열어보면 BasicsCodelabTheme이 MaterialTheme을 사용하여 구현한 것을 확인할 수 있다.

@Composable
fun BasicsCodelabTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }

    MaterialTheme(
        colors = colors,
        typography = typography,
        shapes = shapes,
        content = content
    )
}

MaterialTheme은 컴포저블 함수로 머테리얼 디자인 가이드로부터 스타일링 원칙들을 반영하고 있다. 해당 스타일 정보는 콘텐츠 내부에 있는 컴포넌트들에게 폭포수 형식으로 상위에서 하위로 적용되며, 정보를 읽고 스스로 스타일을 지정할 수 있다. 이미 앱에서 사용하고 있지만, BasicsCodelabTheme을 사용하는 형태를 보면 다음과 같다.

BasicsCodelabTheme {
    MyApp()
}

BasicsCodelabTheme은 MaterialTheme을 내부적으로 상속하기 때문에, MyApp 은 테마에 정의된 속성들로 스타일링 된다. 하위 컴포저블은 MaterialTheme으로부터 colors, typography 그리고 shapes 속성을 가져올 수 있다. 이 속성들을 사용하여 텍스트에 헤더 스타일 중 하나를 적용하자.

Column(modifier = Modifier.weight(1f)) {
    Text(text = "Hello, ")
    Text(text = name, style = MaterialTheme.typography.h4)
}

위 예제에 있는 Text 컴포저블은 새로운 TextStyle을 적용했다. 자신만의 TextStyle을 만들거나 MaterialTheme.typography에 이미 정의된 스타일을 가져올 수도 있다. 이런 방식은 h1-h6, body1, body2, caption, subtitle1 등과 같은 머테리얼로 정의된 텍스트 스타일을 사용할 수 있게 해준다. 예제에서도 정의된 h4 스타일을 사용했다.

이제 빌드하면 새롭게 스타일이 적용된 텍스트를 확인할 수 있다.

일반적으로 MaterialTheme안에 있는 색상, 모양 및 폰트 스타일을 사용하는게 좋다. 예를 들어 하드 코딩된 색상을 사용한다면 다크모드를 구현하기 힘들고, 오류가 발생하기 쉽다.

하지만 때때로 선택한 색상 및 폰트 스타일에서 벗어나야할 때도 있다. 이런 상황에서는 새롭게 전부 다 만드는 것보다는 기존 테마로부터 필요한 부분만 바꾸는 것이 더 나은 선택이 된다.

이를 위해 copy라는 함수를 사용하여 정의된 스타일을 수정할 수 있다. 숫자에 extra bold를 적용해보도록 하자.

Text(
    text = name,
    style = MaterialTheme.typography.h4.copy(
        fontWeight = FontWeight.ExtraBold
    )
)

이 방식은 폰트를 변경하거나 h4의 다른 속성을 변경하는 것과 같은 작업을 할 때 좋다.

이제 preview 윈도우를 통해 결과를 살펴보자

앱 테마 변경하기

현재 테마와 관련된 모든 것들은 ui 폴더내의 파일에서 찾을 수 있다. 예를 들어, 지금까지 사용해 온 기본 색상들은 Color.kt에 정의 되어있다.

새로운 색상을 Color.kt에 추가 해보자.

val Navy = Color(0xFF073042)
val Blue = Color(0xFF4285F4)
val LightBlue = Color(0xFFD7EFFE)
val Chartreuse = Color(0xFFEFF7CF)

이제 위 4가지 색상을 Theme.kt에 있는 MaterialTheme의 팔레트에 적용하자.

private val LightColorPalette = lightColors(
    surface = Blue,
    onSurface = Color.White,
    primary = LightBlue,
    onPrimary = Navy
)

만약 MainActivity.kt로 돌아가서 preview를 다시 리프레시 하면 다음과 같이 새 색상이 적용된 것 화면을 확인할 수 있다.

하지만 아직 다크모드용 색상을 수정하지 않았다. 다크모드용 색상을 수정하기 전에 이를 위한 preview를 설정해보자. @Preview애노테이션의 uiMode 매개변수에 UI_MODE_NIGHT_YES를 추가하자.

@Preview(
    showBackground = true,
    widthDp = 320,
    uiMode = UI_MODE_NIGHT_YES,
    name = "DefaultPreviewDark"
)
@Preview(showBackground = true, widthDp = 320)
@Composable
fun DefaultPreview() {
    BasicsCodelabTheme {
        Greetings()
    }
}

하나의 Composable 함수에 다수의 각기 다른 @Preview를 추가하여 확인할 수 있다. 다크모드용 @Preview 추가하고 나면 DefaultPreviewDark가 preview에 나타난다.

Theme.kt에서 다크모드용 컬러를 정의하자.

private val DarkColorPalette = darkColors(
    surface = Blue,
    onSurface = Navy,
    primary = Navy,
    onPrimary = Chartreuse
)

이제 앱에 테마 및 스타일이 적용된 것을 확인하자.

최종적인 Theme.kt 코드는 다음과 같다.

private val DarkColorPalette = darkColors(
    surface = Blue,
    onSurface = Navy,
    primary = Navy,
    onPrimary = Chartreuse
)

private val LightColorPalette = lightColors(
    surface = Blue,
    onSurface = Color.White,
    primary = LightBlue,
    onPrimary = Navy
)

@Composable
fun BasicsCodelabTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }

    MaterialTheme(
        colors = colors,
        typography = typography,
        shapes = shapes,
        content = content
    )
}
카테고리: Compose

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.