Compose에서 XML 테마를 Material 3으로 이전

기존 앱에 Compose를 도입할 경우 Compose 구성요소에 MaterialTheme을 사용하려면 Material XML 테마를 이전해야 합니다. 그러면 앱의 테마 설정은 뷰 기반 테마와 Compose 테마라는 두 가지 정보 소스를 갖습니다. 스타일 설정 변경은 여러 위치에서 이루어져야 합니다. 앱이 Compose로 완전히 이전되면 XML 테마를 삭제합니다.

Material Theme 빌더 도구를 사용하여 색상을 이전할 수 있습니다.

XML에서 Compose로 마이그레이션을 시작할 때 테마를 Material 3 Compose 테마로 마이그레이션합니다.

용어집

용어 정의
MaterialTheme Compose UI 구성요소에 테마 (색상, 서체, 모양)를 제공하는 컴포저블 함수입니다.
Shape MaterialTheme의 맞춤 구성요소 모양을 정의하는 데 사용되는 Compose 객체입니다.
Typography MaterialTheme의 맞춤 텍스트 스타일 (글꼴 모음, 크기, 두께)을 정의하는 데 사용되는 Compose 객체입니다.
Color 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단계: 맞춤 도형 및 서체 이전하기

  • 앱에서 맞춤 도형을 사용하는 경우:

    1. Compose 코드에서 XML 도형 정의를 복제하는 Shape 객체를 정의합니다.
    2. Shape 객체를 MaterialTheme에 제공합니다.

      자세한 내용은 모양을 참고하세요.

  • 앱에서 맞춤 서체를 사용하는 경우 다음을 충족해야 합니다.

    1. Compose 코드에서 Compose 코드에 Typography 객체를 정의하여 XML 텍스트 스타일과 글꼴 정의를 복제합니다.
    2. Typography 객체를 MaterialTheme에 제공합니다.

      자세한 내용은 서체를 참고하세요.

역할 작성 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) 시스템은 다음의 스타일과 모양을 정의합니다. 1. 위젯, 구성요소, 창 및 대화상자 테마 2. 서체 3. 테마 및 오버레이 4. 도형

XML 뷰와 구성요소는 여러 속성을 결합하여 스타일을 만듭니다. 스타일은 styles.xml에서 두 가지 방법으로 설정합니다. 1. XML 뷰에서 직접 명시적으로 'style="@style/..."'을 설정합니다. 더 큰 테마 (theme.xml)의 일부로 구성요소의 스타일을 간접적으로 암시적으로 설정

스타일은 Compose에 직접 상응하는 항목이 없습니다. 대신 스타일은 컴포저블에 매개변수로 전달되거나, AppTheme에 정의되거나, 정의된 스타일로 재사용 가능한 레이어 컴포저블 변형을 만들어 전달됩니다.

스타일과 기본 구성요소에 따라 이름이 지정된 별도의 @Composable 함수를 제공하여 이러한 구성요소의 스타일과 사용 사례의 차이를 나타냅니다.

  • 패턴: XML 요소가 맞춤 스타일(예: style="@style/MyPrimaryButton")을 사용하는 경우 스타일을 인라인으로 복제하려고 하지 마세요. 대신 특정 컴포저블을 만들라고 제안합니다.
  • 예:
    • XML: <Button style="@style/MyPrimaryButton" ... />
    • 작성: MyPrimaryButton(onClick = { ... })
  • 일반 속성 그룹: 스타일이 일반 수정자(예: 패딩 + 높이)를 설정하는 경우 읽을 수 있는 확장 프로그램 속성이나 공유 수정자 변수로 추출합니다.

일반적인 예

XML Compose
Theme.MaterialComponents.* MaterialTheme(colorScheme, typography, shapes) { }
TextAppearance.Material3.BodyMedium Typography(bodyMedium = ...)에 정의된 TextStyle(...)
ShapeAppearance.*.SmallComponent Shapes(small = RoundedCornerShape(X.dp))
Widget.MaterialComponents.Button Button(colors = ButtonDefaults.buttonColors(...))
Widget.MaterialComponents.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 TextStylefontSize = X.sp

6단계: 테마 이전 유효성 검사

항상 원래 XML 테마의 기존 테마 값을 Compose의 새 Material Theme의 정보 소스로 사용하세요. 브랜드 일관성을 유지하고 시각적 회귀를 방지하기 위해 마이그레이션 중에 새 테마 값을 만들지 마세요.

모든 새 Compose 테마 값이 기존 XML 값과 일치하는지 확인합니다. 이전된 값을 하드코딩하지 마세요.