Jetpack Compose mempermudah desain dan pembuatan UI aplikasi Anda. Compose mengubah status menjadi elemen UI, melalui:
- Komposisi elemen
- Tata letak elemen
- Gambar elemen
Dokumen ini berfokus pada tata letak elemen, yang menjelaskan beberapa elemen penyusun yang disediakan Compose untuk membantu Anda menata elemen UI.
Sasaran tata letak di Compose
Implementasi Jetpack Compose sistem tata letak memiliki dua sasaran utama:
- Performa tinggi
- Kemampuan untuk menulis tata letak kustom dengan mudah
Dasar-dasar fungsi composable
Fungsi yang dapat dikomposisi adalah elemen dasar penyusun Compose. Fungsi yang dapat dikomposisi
adalah fungsi yang menampilkan Unit
yang mendeskripsikan beberapa bagian UI Anda. Fungsi ini mengambil
beberapa input dan menghasilkan apa yang ditampilkan di layar. Untuk mengetahui informasi selengkapnya tentang
composable, lihat dokumentasi Model
mental Compose.
Fungsi composable dapat memunculkan beberapa elemen UI. Namun, jika Anda tidak memberikan panduan tentang cara mengaturnya, Compose mungkin akan mengatur elemen dengan cara yang tidak Anda sukai. Misalnya, kode ini menghasilkan dua elemen teks:
@Composable fun ArtistCard() { Text("Alfred Sisley") Text("3 minutes ago") }
Tanpa panduan tentang cara Anda ingin mengaturnya, Compose akan menumpuk elemen teks di atas satu sama lain, sehingga tidak dapat dibaca:
Compose menyediakan kumpulan tata letak yang siap pakai untuk membantu Anda mengatur elemen UI, dan memudahkan Anda menentukan tata letak sendiri yang lebih khusus.
Komponen tata letak standar
Sering kali, Anda cukup menggunakan elemen tata letak standar Compose.
Gunakan
Column
untuk menempatkan item secara vertikal di layar.
@Composable fun ArtistCardColumn() { Column { Text("Alfred Sisley") Text("3 minutes ago") } }
Demikian pula, gunakan
Row
untuk menempatkan item secara horizontal di layar. Baik Column
maupun Row
mendukung
konfigurasi penyelarasan elemen di dalamnya.
@Composable fun ArtistCardRow(artist: Artist) { Row(verticalAlignment = Alignment.CenterVertically) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { Text(artist.name) Text(artist.lastSeenOnline) } } }
Gunakan Box
untuk menempatkan elemen di atas elemen lainnya. Box
juga mendukung konfigurasi perataan tertentu dari elemen yang ada di dalamnya.
@Composable fun ArtistAvatar(artist: Artist) { Box { Image(bitmap = artist.image, contentDescription = "Artist image") Icon(Icons.Filled.Check, contentDescription = "Check mark") } }
Terkadang, hanya elemen penyusun inilah yang Anda butuhkan. Anda dapat menulis fungsi yang dapat dikomposisi sendiri untuk menggabungkan tata letak ini ke dalam tata letak yang lebih rumit, yang sesuai dengan aplikasi Anda.
Untuk menyetel posisi turunan dalam Row
, setel argumen horizontalArrangement
dan verticalAlignment
. Untuk Column
, setel argumen verticalArrangement
dan
horizontalAlignment
:
@Composable fun ArtistCardArrangement(artist: Artist) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.End ) { Image(bitmap = artist.image, contentDescription = "Artist image") Column { /*...*/ } } }
Model tata letak
Pada model tata letak, hierarki UI diletakkan dalam satu penerusan. Setiap node pertama-tama diminta untuk mengukur dirinya sendiri, lalu mengukur setiap turunan secara rekursif, yang meneruskan batasan ukuran ke hierarki bawah pada turunan. Lalu, node daun diukur dan ditempatkan, dengan ukuran dan petunjuk penempatan yang telah di-resolve diteruskan kembali ke hierarki atas.
Singkatnya, induk diukur sebelum turunannya, tetapi mendapatkan pengubahan ukuran dan penempatan setelah turunannya.
Perhatikan fungsi SearchResult
berikut.
@Composable fun SearchResult() { Row { Image( // ... ) Column { Text( // ... ) Text( // ... ) } } }
Fungsi ini menghasilkan hierarki UI berikut.
SearchResult
Row
Image
Column
Text
Text
Dalam contoh SearchResult
, tata letak hierarki UI mengikuti urutan ini:
- Node root
Row
diminta untuk mengukur. - Node root
Row
meminta pengukuran turunan pertamanya,Image
. Image
adalah node daun (yaitu yang tidak memiliki turunan), sehingga melaporkan ukuran dan menampilkan petunjuk penempatan.- Node root
Row
meminta pengukuran turunan keduanya,Column
. - Node
Column
meminta pengukuran turunanText
pertamanya. - Node
Text
pertama adalah node daun, sehingga melaporkan ukuran dan menampilkan petunjuk penempatan. - Node
Column
meminta pengukuran turunan keduanya,Text
. - Node
Text
kedua adalah node daun, sehingga melaporkan ukuran dan menampilkan petunjuk penempatan. - Setelah node
Column
menyelesaikan pengukuran, pengubahan ukuran, dan menempatkan turunannya, node tersebut dapat menentukan ukuran dan penempatannya sendiri. - Setelah node root
Row
menyelesaikan pengukuran, pengubahan ukuran, dan menempatkan turunannya, node root tersebut dapat menentukan ukuran dan penempatannya sendiri.
Performa
Compose mencapai performa tinggi dengan mengukur turunan hanya satu kali. Pengukuran single-pass baik untuk performa, memungkinkan Compose menangani hierarki UI yang dalam secara efisien. Jika elemen mengukur turunannya dua kali dan turunan itu mengukur setiap turunannya dua kali dan seterusnya, satu upaya untuk membuat tata letak seluruh UI harus melakukan banyak pekerjaan, sehingga sulit untuk menjaga aplikasi tetap berperforma tinggi.
Jika tata letak Anda memerlukan beberapa pengukuran karena alasan tertentu, Compose menawarkan sistem khusus, yaitu pengukuran intrinsik. Anda dapat membaca fitur ini lebih lanjut di Pengukuran intrinsik di tata letak Compose.
Karena pengukuran dan penempatan adalah sub-fase penerusan tata letak yang berbeda, setiap perubahan yang hanya memengaruhi penempatan item, bukan pengukuran, dapat dijalankan secara terpisah.
Menggunakan pengubah dalam tata letak
Seperti yang dibahas dalam Pengubah Compose, Anda dapat menggunakan
pengubah untuk mendekorasi atau meningkatkan composable. Pengubah sangat penting
untuk menyesuaikan tata letak. Misalnya, di sini kita membuat rantai beberapa pengubah
untuk menyesuaikan ArtistCard
:
@Composable fun ArtistCardModifiers( artist: Artist, onClick: () -> Unit ) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { Row(verticalAlignment = Alignment.CenterVertically) { /*...*/ } Spacer(Modifier.size(padding)) Card( elevation = CardDefaults.cardElevation(defaultElevation = 4.dp), ) { /*...*/ } } }
Dalam kode di atas, perhatikan berbagai fungsi pengubah yang digunakan bersama-sama.
clickable
membuat composable bereaksi terhadap input pengguna dan menampilkan ripple.padding
menempatkan ruang di sekitar elemen.fillMaxWidth
membuat composable mengisi lebar maksimum yang diberikan kepadanya dari induknya.size()
menentukan lebar dan tinggi yang dipilih untuk elemen.
Tata letak yang dapat di-scroll
Pelajari lebih lanjut tata letak yang dapat di-scroll dalam Dokumentasi gestur Compose.
Untuk daftar dan daftar lambat, lihat Dokumentasi daftar Compose.
Layout responsif
Tata letak harus didesain dengan mempertimbangkan berbagai orientasi layar dan ukuran faktor bentuk. Compose menawarkan beberapa mekanisme untuk memfasilitasi penyesuaian tata letak composable ke berbagai konfigurasi layar.
Batasan
Untuk mengetahui batasan yang berasal dari induk dan mendesain tata letak yang sesuai, Anda dapat menggunakan BoxWithConstraints
. Batasan pengukuran dapat ditemukan dalam cakupan lambda konten. Anda dapat menggunakan batasan pengukuran ini untuk membuat tata letak yang berbeda untuk konfigurasi layar yang berbeda:
@Composable fun WithConstraintsComposable() { BoxWithConstraints { Text("My minHeight is $minHeight while my maxWidth is $maxWidth") } }
Tata letak berbasis slot
Compose menyediakan berbagai macam composable berdasarkan Desain Material dengan dependensi androidx.compose.material:material
(disertakan saat membuat project Compose di Android Studio) agar proses mem-build UI menjadi lebih mudah. Elemen seperti
Drawer
,
FloatingActionButton
,
dan TopAppBar
semuanya disediakan.
Komponen material banyak menggunakan API slot, yakni sebuah pola yang dibuat Compose
untuk menghadirkan lapisan penyesuaian di atas composable. Pendekatan ini membuat komponen lebih fleksibel, karena menerima elemen turunan yang dapat mengonfigurasi sendiri, bukan harus menampilkan setiap parameter konfigurasi turunan.
Slot memberikan ruang kosong di UI untuk diisi developer, sesuai keinginan mereka. Misalnya,
ini adalah slot yang dapat Anda sesuaikan dalam
TopAppBar
:
Komponen biasanya menggunakan lambda komponen content
( content: @Composable
() -> Unit
). API slot menampilkan beberapa parameter content
untuk penggunaan tertentu.
Misalnya, TopAppBar
memungkinkan Anda menyediakan konten untuk title
,
navigationIcon
, dan actions
.
Misalnya,
Scaffold
memungkinkan Anda menerapkan UI dengan struktur tata letak Desain Material dasar.
Scaffold
menyediakan slot untuk komponen Material tingkat atas yang paling umum,
seperti TopAppBar
,
BottomAppBar
,
FloatingActionButton
,
dan Drawer
. Dengan menggunakan
Scaffold
, sangat mudah untuk memastikan komponen ini diposisikan dengan benar dan
bekerja bersama dengan benar.
@Composable fun HomeScreen(/*...*/) { ModalNavigationDrawer(drawerContent = { /* ... */ }) { Scaffold( topBar = { /*...*/ } ) { contentPadding -> // ... } } }
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Pengubah Compose
- Kotlin untuk Jetpack Compose
- Komponen Material dan tata letak