기존 앱에 Compose를 도입할 경우 Compose 구성요소에 MaterialTheme을 사용하려면 Material XML 테마를 이전해야 합니다. 그러면 앱의 테마 설정은 뷰 기반 테마와 Compose 테마라는 두 가지 정보 소스를 갖습니다. 스타일 설정 변경은 여러 위치에서 이루어져야 합니다. 앱이 Compose로 완전히 이전되면 XML 테마를 삭제합니다.
Material Theme 빌더 도구를 사용하여 색상을 이전할 수 있습니다.
XML에서 Compose로 마이그레이션을 시작할 때 테마를 Material 3 Compose 테마로 마이그레이션합니다.
용어집
| 용어 | 정의 |
|---|---|
MaterialTheme |
Compose UI 구성요소에 테마 (색상, 서체, 모양)를 제공하는 컴포저블 함수입니다. |
Shapes |
MaterialTheme의 맞춤 구성요소 모양을 정의하는 데 사용되는 Compose 객체입니다. |
Typography |
MaterialTheme의 맞춤 텍스트 스타일 (글꼴 모음, 크기, 두께)을 정의하는 데 사용되는 Compose 객체입니다. |
ColorScheme |
MaterialTheme의 맞춤 색 구성표를 정의하는 데 사용되는 Compose 객체입니다. |
| XML 테마 | XML 파일에 정의되어 뷰 시스템에서 사용되는 Android 테마 시스템입니다. |
제한사항
마이그레이션하기 전에 다음 제한사항에 유의하세요.
- 이 가이드에서는 Material 3로의 이전만 중점적으로 설명합니다. 대체 디자인 시스템에서 이전하는 방법은 Material 2 또는 Compose의 맞춤 디자인 시스템을 참고하세요.
- 궁극적인 목표는 Compose로 완전히 이전하여 XML 테마를 삭제하는 것입니다. 이 가이드에서는 이전 방법을 설명하지만 최종적으로 XML 테마를 삭제하는 방법은 설명하지 않습니다.
1단계: 디자인 시스템 평가
XML 뷰 프로젝트에서 사용되는 디자인 시스템을 식별합니다. 기존 디자인 시스템을 Compose의 Material 3으로 이전하기 위한 이전 경로와 필요한 단계를 분석합니다.
2단계: 테마 소스 파일 식별
XML에서는 ?attr/colorPrimary라고 씁니다. Compose에서는 MaterialTheme.*를 사용하여 테마 값에 액세스합니다.
테마 설정에 필요한 모든 XML 리소스와 파일(밝은 색상과 어두운 색상, 한정자, 테마, 모양, 크기, 서체, 스타일, 기타 관련 파일)을 식별하고 찾습니다.
문자열과 같은 리소스는 그대로 재사용할 수 있으며 마이그레이션할 필요가 없습니다.
3단계: 색상 이전
핵심 원칙: XML은 이름이 지정된 16진수 색상을 사용합니다.
Material 3에서는 시맨틱 역할 (예: primary, onPrimary, surface)을 사용합니다. 16진수로 색상 이름을 지정하지 말고 역할로 이름을 지정하세요.
예:
| XML 색상 이름 | Material 3 역할 |
|---|---|
colorPrimary |
primary |
colorPrimaryDark/colorPrimaryVariant |
primaryContainer 또는 secondary |
colorAccent |
secondary 또는 tertiary |
colorOnPrimary |
onPrimary |
android:colorBackground |
background |
colorSurface |
surface |
colorOnSurface |
onSurface |
colorError |
error |
colorOnError |
onError |
colorOutline |
outline |
colorSurfaceVariant |
surfaceVariant |
colorOnSurfaceVariant |
onSurfaceVariant |
어두운 색 구성표와 밝은 색 구성표를 XML에서 Material 3 Compose의 상응하는 색 구성표로 이전합니다.
4단계: 맞춤 도형 및 서체 이전하기
앱에서 맞춤 도형을 사용하는 경우:
- Compose 코드에서 XML 도형 정의를 복제하는
Shapes객체를 정의합니다. 이
Shapes객체를MaterialTheme에 제공합니다.자세한 내용은 모양을 참고하세요.
- Compose 코드에서 XML 도형 정의를 복제하는
앱에서 맞춤 서체를 사용하는 경우 다음을 충족해야 합니다.
- Compose 코드에서 Compose 코드에
Typography객체를 정의하여 XML 텍스트 스타일과 글꼴 정의를 복제합니다. 이
Typography객체를MaterialTheme에 제공합니다.자세한 내용은 서체를 참고하세요.
- Compose 코드에서 Compose 코드에
| 역할 작성 | XML 이름 |
|---|---|
displayLarge |
TextAppearance.Material3.DisplayLarge |
displayMedium |
TextAppearance.Material3.DisplayMedium |
displaySmall |
TextAppearance.Material3.DisplaySmall |
headlineLarge |
TextAppearance.Material3.HeadlineLarge |
headlineMedium |
TextAppearance.Material3.HeadlineMedium |
headlineSmall |
TextAppearance.Material3.HeadlineSmall |
titleLarge |
TextAppearance.Material3.TitleLarge |
titleMedium |
TextAppearance.Material3.TitleMedium |
titleSmall |
TextAppearance.Material3.TitleSmall |
bodyLarge |
TextAppearance.Material3.BodyLarge |
bodyMedium |
TextAppearance.Material3.BodyMedium |
bodySmall |
TextAppearance.Material3.BodySmall |
labelLarge |
TextAppearance.Material3.LabelLarge |
labelMedium |
TextAppearance.Material3.LabelMedium |
labelSmall |
TextAppearance.Material3.LabelSmall |
5단계: 스타일 이전 (styles.xml)
XML 스타일 (styles.xml) 시스템은 다음의 스타일과 모양을 정의합니다.
- 위젯, 구성요소, 창 및 대화상자 테마
- 서체
- 테마 및 오버레이
- 도형
XML 뷰와 구성요소는 여러 속성을 결합하여 스타일을 만듭니다. 스타일은 styles.xml에서 두 가지 방법으로 설정합니다.
- XML 뷰에서 직접 명시적으로 'style="@style/..."' 설정
- 더 큰 테마 (theme.xml)의 일부로 구성요소의 스타일을 간접적으로 암시적으로 설정
스타일은 Compose에 직접 상응하는 항목이 없습니다. 대신 스타일은 AppTheme에 정의된 새 실험용 스타일 API를 사용하여 또는 정의된 스타일로 계층화된 재사용 가능한 컴포저블 변형을 만들어 컴포저블에 매개변수나 수정자로 전달됩니다.
스타일과 기본 구성요소에 따라 이름이 지정된 별도의 @Composable 함수를 제공하여 이러한 구성요소의 스타일과 사용 사례의 차이를 나타냅니다.
- 패턴: XML 요소가 맞춤 스타일(예:
style="@style/MyPrimaryButton")을 사용하는 경우 스타일을 인라인으로 복제하려고 하지 마세요. 대신 특정 컴포저블을 만들라고 제안합니다. - 예:
- XML:
<Button style="@style/MyPrimaryButton" ... /> - 작성:
MyPrimaryButton(onClick = { ... })
- XML:
- 일반 속성 그룹: 스타일이 일반 수정자(예: 패딩 + 높이)를 설정하는 경우 읽을 수 있는 확장 프로그램 속성이나 공유 수정자 변수로 추출합니다.
일반적인 예
| XML | Compose |
|---|---|
Theme.Material3.* |
MaterialTheme(colorScheme, typography, shapes) { } |
TextAppearance.Material3.BodyMedium |
Typography(bodyMedium = ...)에 정의된 TextStyle(...) |
ShapeAppearance.*.SmallComponent |
Shapes(small = RoundedCornerShape(X.dp)) |
Widget.Material3.Button |
Button(colors = ButtonDefaults.buttonColors(...)) |
Widget.Material3.CardView |
Card(shape=..., elevation=..., colors=...) |
Widget.*.TextInputLayout.OutlinedBox |
OutlinedTextField(colors = OutlinedTextFieldDefaults.colors(...)) |
Widget.*.Chip.Filter |
FilterChip(colors = FilterChipDefaults.filterChipColors(...)) |
Widget.*.Toolbar.Primary |
TopAppBar(colors = TopAppBarDefaults.topAppBarColors(...)) |
Widget.*.FloatingActionButton |
FloatingActionButton(containerColor = ...) |
backgroundTint |
ComponentDefaults.ComponentColors()의 containerColor |
android:textColor |
ComponentDefaults.ComponentColors()의 contentColor |
cornerRadius |
shape = RoundedCornerShape(X.dp) |
android:elevation |
elevation = ComponentDefaults.elevation(defaultElevation = X.dp) |
android:padding |
contentPadding = PaddingValues(...) 또는 Modifier.padding() |
android:minHeight |
Modifier.heightIn(min = X.dp) |
strokeColor + strokeWidth |
border = BorderStroke(width, color) |
android:textSize |
TextStyle의 fontSize = X.sp |
6단계: 테마 이전 유효성 검사
항상 원래 XML 테마의 기존 테마 값을 Compose의 새 Material 테마의 정보 소스로 사용하세요. 브랜드 일관성을 유지하고 시각적 회귀를 방지하기 위해 이전 중에 새 테마 값을 만들지 마세요.
모든 새 Compose 테마 값이 기존 XML 값과 일치하는지 확인합니다. 이전된 값을 하드코딩하지 마세요.