Anatomie d'un thème dans Compose

Les thèmes de Jetpack Compose sont constitués d'un certain nombre de constructions de niveau inférieur et d'API associées. Ils sont visibles dans le code source de MaterialTheme et peuvent également être appliqués dans des systèmes de conception personnalisés.

Classes de systèmes de thèmes

Un thème est généralement constitué de plusieurs systèmes qui regroupent des concepts visuels et comportementaux courants. Ces systèmes peuvent être modélisés avec des classes qui ont des valeurs de thématisation.

Par exemple, MaterialTheme inclut Colors (système de couleurs), Typography (système de typographies) et Shapes (système de formes).

@Immutable
data class ColorSystem(
    val color: Color,
    val gradient: List<Color>
    /* ... */
)

@Immutable
data class TypographySystem(
    val fontFamily: FontFamily,
    val textStyle: TextStyle
)
/* ... */

@Immutable
data class CustomSystem(
    val value1: Int,
    val value2: String
    /* ... */
)

/* ... */

CompositionLocals de systèmes de thèmes

Les classes de systèmes de thème sont fournies implicitement à l'arborescence de composition en tant qu'instances CompositionLocal. Cela permet de référencer des valeurs de thématisation de manière statique dans des fonctions modulables.

Pour en savoir plus sur CompositionLocal, consultez le guide Données à champ d'application local avec CompositionLocal.

val LocalColorSystem = staticCompositionLocalOf {
    ColorSystem(
        color = Color.Unspecified,
        gradient = emptyList()
    )
}

val LocalTypographySystem = staticCompositionLocalOf {
    TypographySystem(
        fontFamily = FontFamily.Default,
        textStyle = TextStyle.Default
    )
}

val LocalCustomSystem = staticCompositionLocalOf {
    CustomSystem(
        value1 = 0,
        value2 = ""
    )
}

/* ... */

Fonction de thème

La fonction du thème est le point d'entrée et l'API principale. Elle construit des instances des CompositionLocals de systèmes de thème, en utilisant les valeurs réelles de n'importe quelle logique requises, fournies à l'arborescence de composition avec CompositionLocalProvider. Le paramètre content permet aux composables imbriqués d'accéder aux valeurs de thématisation relatives à la hiérarchie.

@Composable
fun Theme(
    /* ... */
    content: @Composable () -> Unit
) {
    val colorSystem = ColorSystem(
        color = Color(0xFF3DDC84),
        gradient = listOf(Color.White, Color(0xFFD7EFFF))
    )
    val typographySystem = TypographySystem(
        fontFamily = FontFamily.Monospace,
        textStyle = TextStyle(fontSize = 18.sp)
    )
    val customSystem = CustomSystem(
        value1 = 1000,
        value2 = "Custom system"
    )
    /* ... */
    CompositionLocalProvider(
        LocalColorSystem provides colorSystem,
        LocalTypographySystem provides typographySystem,
        LocalCustomSystem provides customSystem,
        /* ... */
        content = content
    )
}

Objet de thème

L'accès aux systèmes de thème s'effectue via un objet doté de propriétés pratiques. Par souci de cohérence, l'objet est généralement nommé de la même manière que la fonction de thème. Les propriétés obtiennent simplement le CompositionLocal actuel.

// Use with eg. Theme.colorSystem.color
object Theme {
    val colorSystem: ColorSystem
        @Composable
        get() = LocalColorSystem.current
    val typographySystem: TypographySystem
        @Composable
        get() = LocalTypographySystem.current
    val customSystem: CustomSystem
        @Composable
        get() = LocalCustomSystem.current
    /* ... */
}