Migrer des thèmes XML vers Material 3 dans Compose

Lorsque vous intégrez Compose dans une application existante, vous devez migrer vos thèmes XML Material pour utiliser MaterialTheme pour les composants Compose. Cela signifie que le thème de votre application combine deux sources de référence, l'une basée sur les vues et l'autre sur Compose. Vous devez donc effectuer plusieurs fois les éventuelles modifications que vous apportez à votre style. Une fois votre application entièrement migrée vers Compose, supprimez votre thème XML.

Vous pouvez utiliser l'outil Material Theme Builder pour migrer les couleurs.

Lorsque vous commencez la migration de XML vers Compose, migrez le thème vers le thème Material 3 Compose.

Glossaire

Terme Définition
MaterialTheme Fonction composable qui fournit un thème (couleurs, typographie, formes) aux composants d'interface utilisateur Compose.
Shapes Objet Compose utilisé pour définir des formes de composants personnalisées pour un MaterialTheme.
Typography Objet Compose utilisé pour définir des styles de texte personnalisés (familles de polices, tailles, épaisseurs) pour un MaterialTheme.
ColorScheme Objet Compose utilisé pour définir des schémas de couleurs personnalisés pour MaterialTheme.
Thème XML Système de thèmes Android défini dans des fichiers XML, utilisé par le système de vues.

Limites

Avant de procéder à la migration, tenez compte des limites suivantes :

  • Ce guide se concentre uniquement sur la migration vers Material 3. Pour migrer depuis d'autres systèmes de conception, consultez Material 2 ou Systèmes de conception personnalisés dans Compose.
  • L'objectif ultime est une migration complète vers Compose, qui permet de supprimer le thème XML. Ce guide explique comment effectuer la migration, mais pas comment supprimer définitivement le thème XML.

Étape 1 : Évaluer le système de conception

Identifiez le système de conception utilisé dans le projet de vue XML. Analysez le chemin de migration et les étapes nécessaires pour migrer le système de conception existant vers Material 3 dans Compose.

Étape 2 : Identifier les fichiers sources du thème

En XML, vous écrivez ?attr/colorPrimary. Dans Compose, vous accédez aux valeurs de thème avec MaterialTheme.* :

Identifiez et localisez toutes les ressources et tous les fichiers XML nécessaires pour le thème : jeux de couleurs clairs et sombres, et qualificatifs, thèmes, formes, dimensions, typographie, styles et autres fichiers pertinents.

Les ressources telles que les chaînes peuvent être réutilisées telles quelles et n'ont pas besoin d'être migrées.

Étape 3 : Migrer les couleurs

Principe clé : XML utilise des couleurs hexadécimales nommées. Material 3 utilise des rôles sémantiques (par exemple, primary, onPrimary, surface). Arrêtez de nommer les couleurs par leur code hexadécimal et nommez-les par leur rôle.

Exemples :

Nom de la couleur XML Rôle Material 3
colorPrimary primary
colorPrimaryDark / colorPrimaryVariant primaryContainer ou secondary
colorAccent secondary ou tertiary
colorOnPrimary onPrimary
android:colorBackground background
colorSurface surface
colorOnSurface onSurface
colorError error
colorOnError onError
colorOutline outline
colorSurfaceVariant surfaceVariant
colorOnSurfaceVariant onSurfaceVariant

Migrez les schémas de couleurs clairs et sombres de XML vers leurs équivalents dans Material 3 Compose.

Étape 4 : Migrer les formes et la typographie personnalisées

  • Si votre application utilise des formes personnalisées :

    1. Dans votre code Compose, définissez un objet Shapes pour répliquer vos définitions de formes XML.
    2. Fournissez cet objet Shapes à votre MaterialTheme.

      Pour en savoir plus, consultez la section Formes.

  • Si votre application utilise une typographie personnalisée :

    1. Dans votre code Compose, définissez un objet Typography pour répliquer vos styles de texte et définitions de polices XML.
    2. Fournissez cet objet Typography à votre MaterialTheme.

      Pour en savoir plus, consultez la section Typographie.

Rôle Compose Nom 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

Étape 5 : Migrer les styles (styles.xml)

Le système de styles XML (styles.xml) définit les styles et l'apparence des éléments suivants :

  1. Widgets, composants, thèmes pour les fenêtres et les boîtes de dialogue
  2. Typographie
  3. Thèmes et superpositions
  4. Formes

Les vues et les composants XML combinent plusieurs attributs pour créer un style. Ils définissent leurs styles à partir de styles.xml de deux manières différentes :

  1. Définir "style="@style/..." directement et explicitement dans la vue XML
  2. Définir le style indirectement et implicitement pour un composant dans le cadre d'un thème plus vaste (theme.xml)

Les styles n'ont pas d'équivalent direct dans Compose. Ils sont transmis en tant que paramètres ou modificateurs aux composables, à l'aide de la nouvelle API Styles expérimentale définie dans AppTheme, ou en créant des variations composables réutilisables et superposées avec le style défini.

Fournissez des fonctions @Composable distinctes nommées en fonction du style et du composant de base, afin de signaler la différence de style et les cas d'utilisation de ces composants.

  • Modèle : si un élément XML utilise un style personnalisé (par exemple, style="@style/MyPrimaryButton"), n'essayez pas de répliquer le style en ligne. À la place, suggérez de créer un composable spécifique.
  • Exemple :
    • XML: <Button style="@style/MyPrimaryButton" ... />
    • Compose : MyPrimaryButton(onClick = { ... })
  • Groupes d'attributs courants : si un style définit des modificateurs courants (comme le remplissage + la hauteur), extrayez-les dans une propriété d'extension lisible ou une variable Modifier partagée.

Exemples courants

XML Compose
Theme.Material3.* MaterialTheme(colorScheme, typography, shapes) { }
TextAppearance.Material3.BodyMedium TextStyle(...) défini dans Typography(bodyMedium = ...)
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 containerColor dans ComponentDefaults.ComponentColors()
android:textColor contentColor dans ComponentDefaults.ComponentColors()
cornerRadius shape = RoundedCornerShape(X.dp)
android:elevation elevation = ComponentDefaults.elevation(defaultElevation = X.dp)
android:padding contentPadding = PaddingValues(...) ou Modifier.padding()
android:minHeight Modifier.heightIn(min = X.dp)
strokeColor + strokeWidth border = BorderStroke(width, color)
android:textSize fontSize = X.sp dans TextStyle

Étape 6 : Valider la migration du thème

Utilisez toujours les valeurs de thème existantes du thème XML d'origine comme source de référence pour le nouveau thème Material dans Compose. N'inventez jamais de nouvelles valeurs de thème lors de la migration, afin de maintenir la cohérence de la marque et d'éviter les régressions visuelles.

Vérifiez que toutes les nouvelles valeurs de thème Compose correspondent aux valeurs XML existantes. Ne codez en dur aucune valeur migrée.