Tema dalam Compose

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Jetpack Compose memudahkan memberi tampilan dan nuansa yang konsisten pada aplikasi Anda dengan menerapkan tema. Anda dapat menyesuaikan penerapan Compose untuk Desain Material agar sesuai dengan brand produk Anda. Jika hal tersebut tidak sesuai dengan kebutuhan Anda, Anda dapat membuat sistem desain khusus menggunakan API publik Compose.

Tema di seluruh aplikasi

Jetpack Compose menawarkan implementasi Desain Material, yaitu sistem desain komprehensif untuk membuat antarmuka digital. Komponen Desain Material (tombol, kartu, tombol akses, dan sebagainya) dibuat di atas Tema Material, yang merupakan cara sistematis untuk menyesuaikan Desain Material agar lebih mencerminkan merek produk Anda. Tema Material terdiri dari atribut warna, tipografi, dan bentuk. Saat Anda menyesuaikan atribut ini, perubahan otomatis tercermin dalam komponen yang digunakan untuk membuat aplikasi.

Jetpack Compose mengimplementasikan konsep ini dengan komposisi MaterialTheme:

MaterialTheme(
    colors = …,
    typography = …,
    shapes = …
) {
    // app content
}

Konfigurasikan parameter yang Anda teruskan ke MaterialTheme untuk tema aplikasi Anda.

Dua screenshot yang kontras. Yang pertama menggunakan gaya MaterialTheme default,
screenshot kedua menggunakan gaya yang dimodifikasi.

Gambar 1. Screenshot pertama menunjukkan aplikasi yang tidak mengonfigurasi MaterialTheme, sehingga akan menggunakan gaya default. Screenshot kedua menampilkan aplikasi yang meneruskan parameter ke MaterialTheme untuk menyesuaikan gaya.

Warna

Warna dimodelkan dalam Compose dengan class Color, yaitu sebuah class penyimpanan data sederhana.

val Red = Color(0xffff0000)
val Blue = Color(red = 0f, green = 0f, blue = 1f)

Meskipun Anda dapat mengaturnya sesuka hati (sebagai konstanta tingkat teratas, dalam bentuk tunggal, atau ditentukan sebagai bagian integral), kami sangat menyarankan untuk menentukan warna dalam tema Anda dan mengambil warna dari sana. Pendekatan ini memungkinkan untuk mendukung beberapa tema, seperti tema gelap.

Contoh palet warna tema

Compose menyediakan class Colors untuk membuat model Sistem warna material. Colors menyediakan fungsi builder untuk membuat kumpulan warna terang atau gelap:

private val Yellow200 = Color(0xffffeb46)
private val Blue200 = Color(0xff91a4fc)
// ...

private val DarkColors = darkColors(
    primary = Yellow200,
    secondary = Blue200,
    // ...
)
private val LightColors = lightColors(
    primary = Yellow500,
    primaryVariant = Yellow400,
    secondary = Blue700,
    // ...
)

Setelah menentukan Colors, Anda dapat meneruskannya ke MaterialTheme:

MaterialTheme(
    colors = if (darkTheme) DarkColors else LightColors
) {
    // app content
}

Menggunakan warna tema

Anda dapat mengambil Colors yang disediakan untuk komposisi MaterialTheme dengan menggunakan MaterialTheme.colors.

Text(
    text = "Hello theming",
    color = MaterialTheme.colors.primary
)

Warna permukaan dan konten

Banyak komponen menerima sepasang warna dan "warna konten":

Surface(
    color: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(color),
    // ...

TopAppBar(
    backgroundColor: Color = MaterialTheme.colors.primarySurface,
    contentColor: Color = contentColorFor(backgroundColor),
    // ...

Hal ini memungkinkan Anda untuk tidak hanya menyetel warna komposisi, tetapi juga memberikan warna default untuk konten, komposisi yang ada di dalamnya. Banyak komposisi menggunakan warna konten ini secara default. Misalnya, Text mendasarkan warnanya pada warna konten induknya, dan Icon menggunakan warna tersebut untuk menetapkan warnanya.

Dua contoh banner yang sama, dengan warna yang berbeda

Gambar 2. Menetapkan warna latar belakang yang berbeda akan menghasilkan warna teks dan ikon yang berbeda.

Metode contentColorFor() mengambil warna "aktif" yang sesuai untuk setiap warna tema. Misalnya, jika Anda menetapkan latar belakang primary, yang menetapkan onPrimary sebagai warna konten. Jika Anda menyetel warna latar belakang non-tema, Anda juga harus menentukan warna konten yang masuk akal. Gunakan LocalContentColor untuk mengambil warna konten saat ini yang kontras dengan latar belakang saat ini.

Alfa Konten

Sering kali kami ingin membedakan seberapa besar kami menekankan konten untuk menyampaikan level nilai penting dan memberikan hierarki visual. Desain Material menyarankan penggunaan berbagai level opasitas untuk menyatakan level nilai penting yang berbeda tersebut.

Jetpack Compose menerapkan ini melalui LocalContentAlpha. Anda dapat menentukan alfa konten untuk hierarki dengan memberikan nilai untuk CompositionLocal. Komponen turunan dapat menggunakan nilai ini, misalnya Text dan Icon secara default menggunakan kombinasi LocalContentColor yang disesuaikan untuk menggunakan LocalContentAlpha. Material menentukan beberapa nilai alfa standar (high, medium, disabled) yang dimodelkan berdasarkan objek ContentAlpha. Perlu diketahui bahwa MaterialTheme akan mendefaultkan LocalContentAlpha ke ContentAlpha.high.

// By default, both Icon & Text use the combination of LocalContentColor &
// LocalContentAlpha. De-emphasize content by setting content alpha
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Text(/*...*/)
}
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Icon(/*...*/)
    Text(/*...*/)
}

Screenshot judul artikel, menampilkan berbagai tingkat emphasis
teks

Gambar 3. Menerapkan berbagai tingkat emphasis pada teks untuk menyampaikan hierarki informasi secara visual.

Tema gelap

Di Compose, Anda menerapkan tema terang dan gelap dengan menyediakan berbagai kumpulan Colors ke komposisi MaterialTheme, dan menggunakan warna melalui tema:

@Composable
fun MyTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    MaterialTheme(
        colors = if (darkTheme) DarkColors else LightColors,
        /*...*/
        content = content
    )
}

Dalam contoh ini, MaterialTheme dikemas dalam fungsi yang dapat dikomposisi, yang menerima parameter yang menentukan apakah akan menggunakan tema gelap atau tidak. Dalam hal ini, fungsi tersebut akan mendapatkan nilai default untuk darkTheme dengan membuat kueri setelan tema perangkat.

Saat menerapkan tema gelap, Anda dapat memeriksa apakah Colors saat ini sedang terang atau gelap:

val isLightTheme = MaterialTheme.colors.isLight

Nilai ini ditetapkan oleh fungsi builder lightColors() dan darkColors().

Pada Material, permukaan tema gelap dengan elevasi yang lebih tinggi menerima overlay elevasi, yang akan mencerahkan latar belakangnya. Overlay ini diterapkan secara otomatis oleh komposisi Surface saat menggunakan warna gelap:

Surface(
    elevation = 2.dp,
    color = MaterialTheme.colors.surface, // color will be adjusted for elevation
    /*...*/
) { /*...*/ }

Screenshot aplikasi, yang menunjukkan warna yang sedikit berbeda dan digunakan untuk elemen
pada tingkat elevasi yang berbeda

Gambar 4. Kartu dan Navigasi Bawah berwarna surface berwarna seperti latar belakang, tetapi karena berada pada elevasi yang lebih tinggi, warnanya sedikit lebih terang.

Memperluas warna Material

Compose dengan cermat mengikuti tema warna Material, mengikuti pedoman material jadi aman dan mudah. Jika Anda perlu memperluas rangkaian warna, Anda dapat menerapkan sistem warna Anda sendiri seperti yang ditunjukkan di bawah ini, atau menambahkan ekstensi:

val Colors.snackbarAction: Color
    @Composable get() = if (isLight) Red300 else Red700

Tipografi

Material menentukan sistem jenis, yang mendorong Anda untuk menggunakan sejumlah kecil gaya dengan nama semantik.

Contoh beberapa jenis huruf yang berbeda dalam berbagai
gaya

Compose menerapkan sistem jenis dengan class Typography, TextStyle, dan terkait font. Konstruktor Typography menawarkan default untuk setiap gaya sehingga Anda dapat menghilangkan gaya yang tidak ingin Anda sesuaikan:

val Rubik = FontFamily(
    Font(R.font.rubik_regular),
    Font(R.font.rubik_medium, FontWeight.W500),
    Font(R.font.rubik_bold, FontWeight.Bold)
)

val MyTypography = Typography(
    h1 = TextStyle(
        fontFamily = Rubik,
        fontWeight = FontWeight.W300,
        fontSize = 96.sp
    ),
    body1 = TextStyle(
        fontFamily = Rubik,
        fontWeight = FontWeight.W600,
        fontSize = 16.sp
    )
    /*...*/
)
MaterialTheme(typography = MyTypography, /*...*/)

Jika Anda ingin menggunakan font yang sama, tentukan parameter defaultFontFamily dan hapus fontFamily dari setiap elemen TextStyle:

val typography = Typography(defaultFontFamily = Rubik)
MaterialTheme(typography = typography, /*...*/)

Menggunakan gaya teks

Ambil TextStyle dari tema, seperti yang ditunjukkan dalam contoh ini:

Text(
    text = "Subtitle2 styled",
    style = MaterialTheme.typography.subtitle2
)

Screenshot yang menunjukkan perpaduan berbagai jenis huruf untuk tujuan berbeda

Gambar 5. Menggunakan pilihan jenis huruf dan gaya untuk mengekspresikan merek Anda.

Bentuk

Material menetapkan sistem bentuk, yang memungkinkan Anda menentukan bentuk untuk komponen besar, sedang, dan kecil.

Menampilkan berbagai bentuk Desain Material

Compose menerapkan sistem bentuk dengan class Shapes, yang memungkinkan Anda menentukan CornerBasedShape untuk masing-masing kategori:

val Shapes = Shapes(
    small = RoundedCornerShape(percent = 50),
    medium = RoundedCornerShape(0f),
    large = CutCornerShape(
        topStart = 16.dp,
        topEnd = 0.dp,
        bottomEnd = 0.dp,
        bottomStart = 16.dp
    )
)

MaterialTheme(shapes = Shapes, /*...*/)

Banyak komponen menggunakan bentuk ini secara default. Misalnya, Button, TextField, dan FloatingActionButton default ke kecil, AlertDialog default ke sedang, dan ModalDrawer default ke besar - lihat referensi skema bentuk untuk pemetaan lengkap.

Menggunakan bentuk

Ambil bentuk dari tema:

Surface(
    shape = MaterialTheme.shapes.medium, /*...*/
) {
    /*...*/
}

Screenshot aplikasi yang menggunakan bentuk Material untuk menyampaikan status elemen
di dalamnya

Gambar 6. Menggunakan bentuk untuk mengekspresikan merek atau status.

Gaya komponen

Tidak ada konsep eksplisit tentang gaya komponen dalam Compose, karena Anda menyediakan fungsi ini dengan membuat komposisi Anda sendiri. Misalnya, untuk membuat gaya tombol, letakkan tombol dalam fungsi Anda sendiri yang dapat dikomposisi, langsung tetapkan parameter yang ingin Anda ubah, dan tampilkan yang lain sebagai parameter ke komposisi yang memuatnya.

@Composable
fun LoginButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    Button(
        colors = ButtonDefaults.buttonColors(
            backgroundColor = MaterialTheme.colors.secondary
        ),
        onClick = onClick,
        modifier = modifier,
        content = content
    )
}

Sistem desain kustom

Meskipun Material adalah sistem desain yang kami rekomendasikan dan Jetpack Compose menghadirkan implementasi Material, Anda tidak dibatasi untuk menggunakannya. Anda dapat membuat sistem desain sendiri dengan cara yang sama; Material dibuat sepenuhnya di API publik yang dapat Anda gunakan untuk mencapainya.

Deskripsi lengkap tentang cara mem-build sistem desain kustom berada di luar cakupan dokumen ini, tetapi lihat referensi berikut:

Pelajari lebih lanjut

Untuk mempelajari lebih lanjut, coba codelab Tema Jetpack Compose.