지금까지는 컴포저블 함수에 어떠한 스타일도 적용하지 않았고, 다크모드 지원을 포함하는 적당한 기본값으로만 코드를 작성했다. 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
)
}
0개의 댓글