Halaman ini menyediakan ringkasan tingkat tinggi tentang lapisan arsitektur yang membentuk Jetpack Compose, dan prinsip inti yang menjadi dasar desain ini.
Jetpack Compose bukan project monolitik tunggal; project ini dibuat dari sejumlah modul yang disusun menjadi satu untuk membentuk stack lengkap. Memahami berbagai modul yang membentuk Jetpack Compose memungkinkan Anda untuk:
- Menggunakan tingkat abstraksi yang sesuai untuk membuat aplikasi atau library
- Memahami kapan Anda dapat melakukan 'drop down' ke level yang lebih rendah untuk kontrol atau penyesuaian lebih lanjut
- Meminimalkan dependensi Anda
Lapisan
Lapisan utama Jetpack Compose adalah:
Gambar 1. Lapisan utama Jetpack Compose.
Setiap lapisan dibuat di atas level yang lebih rendah, dengan menggabungkan fungsi untuk membuat komponen dengan tingkat yang lebih tinggi. Setiap lapisan dibuat di API publik dari lapisan yang lebih rendah untuk memverifikasi batas modul dan memungkinkan Anda mengganti lapisan apa pun yang diperlukan. Mari memeriksa lapisan ini dari bawah ke atas.
- Runtime
- Modul ini memberikan dasar-dasar runtime Compose, seperti
remember
,mutableStateOf
, anotasi@Composable
, danSideEffect
. Sebaiknya Anda membuat lapisan ini secara langsung jika Anda hanya memerlukan kemampuan pengelolaan hierarki Compose, bukan UI-nya. - UI
- Lapisan UI terdiri dari beberapa modul (
ui-text
,ui-graphics
,ui-tooling
, dll.). Modul ini mengimplementasikan dasar-dasar toolkit UI, sepertiLayoutNode
,Modifier
, pengendali input, tata letak kustom, dan gambar. Sebaiknya memanfaatkan lapisan ini jika Anda hanya memerlukan konsep dasar toolkit UI. - Fondasi
- Modul ini memberikan elemen penyusun terpadu desain sistem untuk Compose UI,
seperti
Row
danColumn
,LazyColumn
, mengenali gestur tertentu, dll. Anda dapat mempertimbangkan untuk membuat lapisan dasar guna membuat sistem desain Anda sendiri. - Material
- Modul ini menyediakan implementasi sistem Desain Material untuk Compose UI, yang menyediakan sistem bertema, komponen bergaya, indikasi ripple, dan ikon. Buat lapisan ini saat menggunakan Desain Material di aplikasi Anda.
Prinsip-prinsip desain
Prinsip panduan Jetpack Compose adalah menyediakan beberapa fungsionalitas kecil dan fokus yang dapat disusun (atau dikumpulkan) bersama, bukan beberapa komponen monolitik. Pendekatan ini memiliki sejumlah keuntungan.
Kontrol
Komponen dengan level yang lebih tinggi cenderung melakukan lebih banyak hal untuk Anda, tetapi membatasi kontrol langsung yang Anda miliki. Jika memerlukan kontrol lebih besar, Anda dapat "drop down" untuk menggunakan komponen dengan level lebih rendah.
Misalnya, jika ingin menganimasikan warna komponen, Anda dapat menggunakan
animateColorAsState
API:
val color = animateColorAsState(if (condition) Color.Green else Color.Red)
Namun, jika Anda memerlukan komponen untuk selalu memulai dengan warna abu-abu, Anda tidak dapat
melakukannya dengan API ini. Sebagai gantinya, Anda dapat melakukan drop-down untuk menggunakan
Animatable
API dengan level lebih rendah:
val color = remember { Animatable(Color.Gray) } LaunchedEffect(condition) { color.animateTo(if (condition) Color.Green else Color.Red) }
animateColorAsState
API dengan level yang lebih tinggi itu sendiri dibuat pada
Animatable
API dengan level yang lebih rendah. Penggunaan API dengan level yang lebih rendah lebih kompleks tetapi menawarkan
kontrol lebih besar. Pilih tingkat abstraksi yang paling sesuai dengan kebutuhan Anda.
Penyesuaian
Menyusun komponen dengan level yang lebih tinggi dari elemen dasar yang lebih kecil membuat
penyesuaian komponen yang Anda perlukan jauh lebih mudah. Misalnya, sebaiknya
implementasikan
Button
yang disediakan oleh lapisan Material:
@Composable fun Button( // … content: @Composable RowScope.() -> Unit ) { Surface(/* … */) { CompositionLocalProvider(/* … */) { // set LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { Row( // … content = content ) } } } }
Button
disusun dari 4 komponen:
Material
Surface
yang menyediakan latar belakang, bentuk, penanganan klik, dll.CompositionLocalProvider
yang mengubah alfa konten saat tombol diaktifkan atau dinonaktifkanProvideTextStyle
menyetel gaya teks default yang akan digunakanRow
menyediakan kebijakan tata letak default untuk konten tombol
Kami telah menghilangkan beberapa parameter dan komentar untuk membuat struktur lebih jelas, tetapi
seluruh komponen hanya berisi sekitar 40 baris kode karena hanya
menyusun 4 komponen ini untuk mengimplementasikan tombol. Komponen seperti Button
bersifat dogmatis untuk mengetahui parameter yang diekspos, sehingga menyeimbangkan kemungkinan
penyesuaian umum terhadap ledakan parameter yang dapat membuat komponen
lebih sulit digunakan. Komponen material, misalnya, menawarkan penyesuaian yang ditentukan
dalam sistem Desain Material, sehingga memudahkan untuk mengikuti prinsip
desain material.
Namun, jika ingin membuat penyesuaian di luar parameter komponen,
Anda dapat "drop down" level dan melakukan fork komponen. Misalnya, Desain
Material menetapkan bahwa tombol harus memiliki latar belakang berwarna solid. Jika Anda
memerlukan latar belakang gradien, opsi ini tidak didukung oleh parameter
Button
. Dalam hal ini, Anda dapat menggunakan implementasi Button
Material sebagai
referensi dan membuat komponen Anda sendiri:
@Composable fun GradientButton( // … background: List<Color>, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background( Brush.horizontalGradient(background) ) ) { CompositionLocalProvider(/* … */) { // set material LocalContentAlpha ProvideTextStyle(MaterialTheme.typography.button) { content() } } } }
Implementasi di atas terus menggunakan komponen dari lapisan Material,
seperti konsep Material
alfa konten saat ini
dan gaya teks saat ini. Namun, elemen ini menggantikan Surface
material dengan
Row
dan menata gaya untuk mencapai tampilan yang diinginkan.
Jika tidak ingin menggunakan konsep Material sama sekali, misalnya jika membuat sistem desain khusus pesanan sendiri, Anda dapat melakukan drop-down hanya untuk menggunakan komponen lapisan dasar:
@Composable fun BespokeButton( // … backgroundColor: Color, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Row( // … modifier = modifier .clickable(onClick = {}) .background(backgroundColor) ) { // No Material components used content() } }
Jetpack Compose mencadangkan nama yang paling sederhana untuk komponen dengan level tertinggi. Misalnya,
androidx.compose.material.Text
dibuat berdasarkan
androidx.compose.foundation.text.BasicText
.
Hal ini memungkinkan Anda melakukan implementasi sendiri dengan
nama yang paling mudah ditemukan jika ingin mengganti level yang lebih tinggi.
Memilih abstraksi yang tepat
Filosofi Compose dalam membuat komponen berlapis dan dapat digunakan kembali berarti bahwa Anda tidak boleh selalu menjangkau elemen penyusun level bawah. Banyak komponen dengan level yang lebih tinggi tidak hanya menawarkan lebih banyak fungsi, tetapi sering kali menerapkan praktik terbaik seperti mendukung aksesibilitas.
Misalnya, jika ingin menambahkan dukungan gestur ke komponen kustom, Anda
dapat membuat dari awal menggunakan
Modifier.pointerInput
,
tetapi ada komponen lain dengan level yang lebih tinggi di atas ini, yang mungkin
menawarkan titik awal yang lebih baik, misalnya
Modifier.draggable
,
Modifier.scrollable
atau Modifier.swipeable
.
Biasanya lebih suka membuat komponen level tertinggi yang menawarkan fungsi yang Anda butuhkan untuk mendapatkan manfaat dari praktik terbaik yang disertakannya.
Pelajari lebih lanjut
Lihat contoh Jetsnack untuk mengetahui contoh pembuatan sistem desain kustom.
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Kotlin untuk Jetpack Compose
- Daftar dan petak
- Efek samping di Compose