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.
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.
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.
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(/*...*/)
}
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
/*...*/
) { /*...*/ }
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.
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
)
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.
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, /*...*/
) {
/*...*/
}
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:
- Kode sumber MaterialTheme
- CompositionLocal
- Penyedia
- Aplikasi contoh Jetsnack, yang menerapkan sistem warna kustom
Pelajari lebih lanjut
Untuk mempelajari lebih lanjut, coba codelab Tema Jetpack Compose.