Anatomi tema di Compose

Tema di Jetpack Compose terdiri dari sejumlah konstruksi tingkat rendah dan API terkait. Ini dapat dilihat di kode sumber MaterialTheme dan juga dapat diterapkan di sistem desain kustom.

Class sistem tema

Sebuah tema biasanya terdiri dari sejumlah subsistem yang mengelompokkan visual dan konsep perilaku. Sistem ini dapat dimodelkan dengan class yang memiliki nilai tema.

Misalnya, MaterialTheme menyertakan ColorScheme (sistem warna), Typography (sistem tipografi), dan Shapes (sistem bentuk).

@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
    /* ... */
)

/* ... */

Lokal komposisi sistem tema

Class sistem tema secara implisit disediakan ke hierarki komposisi sebagai instance CompositionLocal. Hal ini memungkinkan nilai tema direferensikan secara statis dalam fungsi yang dapat dikomposisi.

Untuk mempelajari CompositionLocal lebih lanjut, lihat Data yang tercakup secara lokal dengan panduan 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 = ""
    )
}

/* ... */

Fungsi tema

Fungsi tema adalah titik entri dan API utama. Fitur ini membuat instance sistem tema CompositionLocal, menggunakan nilai sebenarnya dari logika apa pun yang diperlukan, yang diberikan ke hierarki komposisi dengan CompositionLocalProvider. Parameter content memungkinkan composable bertingkat untuk mengakses nilai tema yang relatif terhadap hierarki.

@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
    )
}

Objek tema

Mengakses sistem tema dilakukan menggunakan objek dengan properti praktis. Untuk konsistensi, objek cenderung diberi nama yang sama dengan fungsi tema. Properti hanya mendapatkan komposisi lokal saat ini.

// 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
    /* ... */
}