Dalam Compose, elemen UI diwakili oleh fungsi yang dapat dikomposisi yang memancarkan UI saat dipanggil, yang kemudian ditambahkan ke hierarki UI yang dirender di layar. Setiap elemen UI memiliki satu induk dan kemungkinan banyak turunan. Setiap elemen juga berada dalam induknya, yang ditetapkan sebagai posisi (x, y), dan ukuran, yang ditetapkan sebagai width
dan height
.
Induk menentukan batasan untuk elemen turunannya. Sebuah elemen diminta untuk menentukan ukurannya dalam batasan tersebut. Batasan membatasi width
dan height
minimum dan maksimum dari sebuah elemen. Jika suatu elemen memiliki elemen turunan, elemen tersebut dapat mengukur setiap turunan untuk membantu menentukan ukurannya. Setelah elemen menentukan
dan melaporkan ukurannya sendiri, elemen tersebut memiliki peluang untuk menentukan cara menempatkan elemen turunannya secara relatif terhadap dirinya sendiri, seperti yang dijelaskan secara mendetail dalam Membuat tata
letak kustom.
Menetapkan tata letak setiap node di hierarki UI merupakan proses tiga langkah. Setiap node harus:
- Mengukur setiap turunan
- Menentukan ukurannya sendiri
- Menempatkan turunannya
Penggunaan cakupan menentukan kapan Anda dapat mengukur dan menempatkan turunan.
Mengukur tata letak hanya dapat dilakukan selama pengukuran dan tata letak diteruskan,
serta turunan hanya dapat ditempatkan selama tata letak diteruskan (dan hanya setelah
turunan diukur). Karena cakupan Compose seperti
MeasureScope
,
dan PlacementScope
,
ini diterapkan pada waktu kompilasi.
Menggunakan pengubah tata letak
Anda dapat menggunakan pengubah layout
untuk mengubah cara elemen diukur dan ditata letak. Layout
adalah lambda; parameternya mencakup komponen yang dapat diukur,
diteruskan sebagai measurable
, dan batasan composable tersebut yang diteruskan, sebagai
constraints
. Pengubah tata letak kustom dapat terlihat seperti ini:
fun Modifier.customLayoutModifier() = layout { measurable, constraints -> // ... }
Mari kita tampilkan Text
di layar dan kontrol jarak dari atas ke
bagian dasar baris pertama teks. Ini persis yang dilakukan oleh pengubah
paddingFromBaseline
. Kami menerapkannya di sini sebagai contoh.
Untuk melakukannya, gunakan pengubah layout
untuk secara manual menempatkan composable di
layar. Berikut adalah perilaku yang diinginkan saat padding atas Text
disetel 24.dp
:
Inilah kode untuk menghasilkan ruang tersebut:
fun Modifier.firstBaselineToTop( firstBaselineToTop: Dp ) = layout { measurable, constraints -> // Measure the composable val placeable = measurable.measure(constraints) // Check the composable has a first baseline check(placeable[FirstBaseline] != AlignmentLine.Unspecified) val firstBaseline = placeable[FirstBaseline] // Height of the composable with padding - first baseline val placeableY = firstBaselineToTop.roundToPx() - firstBaseline val height = placeable.height + placeableY layout(placeable.width, height) { // Where the composable gets placed placeable.placeRelative(0, placeableY) } }
Inilah yang terjadi dalam kode tersebut:
- Di parameter lambda
measurable
, Anda mengukurText
yang ditunjukkan oleh parameter terukur dengan memanggilmeasurable.measure(constraints)
. - Anda menentukan ukuran composable dengan memanggil metode
layout(width, height)
, yang juga memberikan lambda yang digunakan untuk menempatkan elemen yang digabungkan. Dalam hal ini, tempatnya adalah tinggi antara bagian dasar pengukuran terakhir dan padding atas yang ditambahkan. - Anda dapat memosisikan elemen yang digabungkan di layar dengan memanggil
placeable.place(x, y)
. Jika elemen yang digabungkan tidak ditempatkan, elemen tersebut tidak akan terlihat. Posisiy
sesuai dengan padding atas - yaitu posisi bagian dasar pengukuran pertama teks.
Untuk memverifikasi bahwa tindakan ini berfungsi sebagaimana diharapkan, gunakan pengubah ini pada Text
:
@Preview @Composable fun TextWithPaddingToBaselinePreview() { MyApplicationTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } } @Preview @Composable fun TextWithNormalPaddingPreview() { MyApplicationTheme { Text("Hi there!", Modifier.padding(top = 32.dp)) } }
Membuat tata letak kustom
Pengubah layout
hanya mengubah composable pemanggilan. Untuk mengukur dan menata letak
beberapa composable, gunakan composable Layout
. Composable ini memungkinkan Anda
mengukur dan menata letak turunan secara manual. Semua tata letak di tingkat yang lebih tinggi
seperti Column
dan Row
dibuat dengan composable Layout
.
Mari membuat versi Column
yang sangat dasar. Sebagian besar tata letak kustom mengikuti pola
ini:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // measure and position children given constraints logic here // ... } }
Sama dengan pengubah layout
, measurables
adalah daftar turunan yang perlu diukur dan constraints
adalah pembatas dari induk.
Dengan logika yang sama seperti sebelumnya, MyBasicColumn
dapat diterapkan seperti
ini:
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // Don't constrain child views further, measure them with given constraints // List of measured children val placeables = measurables.map { measurable -> // Measure each children measurable.measure(constraints) } // Set the size of the layout as big as it can layout(constraints.maxWidth, constraints.maxHeight) { // Track the y co-ord we have placed children up to var yPosition = 0 // Place children in the parent layout placeables.forEach { placeable -> // Position item on the screen placeable.placeRelative(x = 0, y = yPosition) // Record the y co-ord placed up to yPosition += placeable.height } } } }
Composable turunan dibatasi oleh batasan Layout
(tanpa batasan minHeight
), dan penempatan tersebut didasarkan pada yPosition
dari composable sebelumnya.
Berikut ini cara penggunaan komponen kustom tersebut:
@Composable fun CallingComposable(modifier: Modifier = Modifier) { MyBasicColumn(modifier.padding(8.dp)) { Text("MyBasicColumn") Text("places items") Text("vertically.") Text("We've done it by hand!") } }
Arah tata letak
Ubah arah tata letak composable dengan mengubah
lokal komposisi LocalLayoutDirection
.
Jika Anda menempatkan composable secara manual di layar, LayoutDirection
adalah bagian dari LayoutScope
dari pengubah layout
atau composable Layout
.
Saat menggunakan layoutDirection
, tempatkan composable menggunakan place
. Tidak seperti metode
placeRelative
,
place
tidak berubah berdasarkan arah tata letak
(dari kiri ke kanan versus kanan ke kiri).
Cara kerja tata letak kustom
Pelajari tata letak dan pengubah lebih lanjut di Tata letak dasar di Compose, dan lihat cara kerja tata letak kustom di Contoh Compose yang membuat tata letak kustom.
Mempelajari lebih lanjut
Untuk mempelajari tata letak kustom di Compose lebih lanjut, lihat referensi tambahan berikut.
Video
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Pengukuran intrinsik di tata letak Compose
- Grafis di Compose
- Pengubah Compose