FlowRow
dan FlowColumn
adalah composable yang mirip dengan Row
dan Column
, tetapi berbeda karena item
mengalir ke baris berikutnya saat penampung kehabisan ruang. Tindakan ini akan membuat
beberapa baris atau kolom. Jumlah item dalam baris juga dapat dikontrol
dengan menyetel maxItemsInEachRow
atau maxItemsInEachColumn
. Anda sering kali dapat menggunakan
FlowRow
dan FlowColumn
untuk membuat tata letak responsif—konten tidak akan terpotong
jika item terlalu besar untuk satu dimensi, dan menggunakan kombinasi
maxItemsInEach*
dengan Modifier.weight(weight)
dapat membantu membuat tata letak yang
mengisi/memperluas lebar baris atau kolom jika diperlukan.
Contoh umumnya adalah untuk chip atau UI pemfilteran:

FlowRow
Penggunaan dasar
Untuk menggunakan FlowRow
atau FlowColumn
, buat composable ini dan tempatkan item
di dalamnya yang harus mengikuti alur standar:
@Composable private fun FlowRowSimpleUsageExample() { FlowRow(modifier = Modifier.padding(8.dp)) { ChipItem("Price: High to Low") ChipItem("Avg rating: 4+") ChipItem("Free breakfast") ChipItem("Free cancellation") ChipItem("£50 pn") } }
Cuplikan ini menghasilkan UI yang ditampilkan di atas, dengan item yang otomatis mengalir ke baris berikutnya jika tidak ada lagi ruang di baris pertama.
Fitur tata letak mengalir
Tata letak alur memiliki fitur dan properti berikut yang dapat Anda gunakan untuk membuat tata letak yang berbeda dalam aplikasi.
Pengaturan sumbu utama: pengaturan horizontal atau vertikal
Sumbu utama adalah sumbu tempat item ditata (misalnya, di
FlowRow
, item disusun secara horizontal). Parameter horizontalArrangement
di FlowRow
mengontrol cara ruang kosong didistribusikan di antara item.
Tabel berikut menunjukkan contoh cara menetapkan horizontalArrangement
pada item
untuk FlowRow
:
Pengaturan horizontal ditetapkan pada |
Hasil |
|
![]() |
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
Untuk FlowColumn
, opsi serupa tersedia dengan verticalArrangement
, dengan
default Arrangement.Top
.
Tata letak sumbu silang
Sumbu silang adalah sumbu dalam arah yang berlawanan dengan sumbu utama. Misalnya, di FlowRow
, ini adalah sumbu vertikal. Untuk mengubah cara penataan keseluruhan
konten di dalam penampung pada sumbu silang, gunakan
verticalArrangement
untuk FlowRow
, dan horizontalArrangement
untuk
FlowColumn
.
Untuk FlowRow
, tabel berikut menunjukkan contoh setelan verticalArrangement
yang berbeda pada item:
Pengaturan vertikal ditetapkan pada |
Hasil |
|
![]() |
![]() |
|
![]() |
Untuk FlowColumn
, opsi serupa tersedia dengan horizontalArrangement
.
Tata letak sumbu silang default adalah Arrangement.Start
.
Penyejajaran item individual
Anda mungkin ingin memosisikan setiap item dalam baris dengan perataan yang berbeda. Hal ini berbeda dengan verticalArrangement
dan
horizontalArrangement
karena menyelaraskan item dalam baris saat ini. Anda dapat
menerapkannya dengan Modifier.align()
.
Misalnya, jika item dalam FlowRow
memiliki tinggi yang berbeda, baris akan mengambil tinggi item terbesar dan menerapkan Modifier.align(alignmentOption)
ke item:
Perataan vertikal ditetapkan pada |
Hasil |
|
![]() |
![]() |
|
![]() |
Untuk FlowColumn
, opsi serupa tersedia. Penyejajaran defaultnya adalah
Alignment.Start
.
Jumlah maksimum item dalam baris atau kolom
Parameter maxItemsInEachRow
atau maxItemsInEachColumn
menentukan jumlah item maksimum di sumbu utama yang diizinkan dalam satu baris sebelum di-wrap ke baris berikutnya. Nilai
defaultnya adalah Int.MAX_INT
, yang memungkinkan sebanyak mungkin item, selama
ukurannya memungkinkan item tersebut masuk ke dalam baris.
Misalnya, menyetel maxItemsInEachRow
akan memaksa tata letak awal hanya
memiliki 3 item:
Tidak ada batas maksimum yang ditetapkan |
|
![]() |
![]() |
Berat item
Bobot memperbesar item berdasarkan faktornya dan ruang yang tersedia di baris tempat item tersebut ditempatkan. Yang penting, ada perbedaan antara FlowRow
dan Row
dalam cara penggunaan bobot untuk menghitung lebar item. Untuk Rows
, weight
didasarkan pada semua item dalam Row
. Dengan FlowRow
, bobot didasarkan pada
item dalam baris tempat item ditempatkan, bukan semua item dalam
penampung FlowRow
.
Misalnya, jika Anda memiliki 4 item yang semuanya berada dalam satu baris, masing-masing dengan
bobot 1f, 2f, 1f
, dan 3f
yang berbeda, total bobotnya adalah 7f
. Ruang yang tersisa
dalam baris atau kolom akan dibagi dengan 7f
. Kemudian, lebar setiap item akan
dihitung menggunakan: weight * (remainingSpace / totalWeight)
.
Anda dapat menggunakan kombinasi Modifier.weight
dan item maks dengan FlowRow
atau
FlowColumn
untuk membuat tata letak seperti petak. Pendekatan ini berguna untuk membuat tata letak responsif yang menyesuaikan ukuran perangkat Anda.
Ada beberapa contoh berbeda tentang apa yang dapat Anda capai menggunakan bobot. Salah satu contohnya adalah petak dengan item berukuran sama, seperti yang ditunjukkan di bawah ini:

FlowRow
untuk membuat petakUntuk membuat petak dengan ukuran item yang sama, Anda dapat melakukan hal berikut:
val rows = 3 val columns = 3 FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = rows ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .weight(1f) .clip(RoundedCornerShape(8.dp)) .background(MaterialColors.Blue200) repeat(rows * columns) { Spacer(modifier = itemModifier) } }
Yang penting, jika Anda menambahkan item lain dan mengulanginya 10 kali, bukan 9 kali, item terakhir akan menempati seluruh kolom terakhir, karena total bobot untuk seluruh baris adalah 1f
:

FlowRow
untuk membuat petak dengan item terakhir yang menempati lebar penuhAnda dapat menggabungkan bobot dengan Modifiers
lainnya seperti
Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
, atau
Modifier.fillMaxWidth(fraction)
. Semua pengubah ini bekerja bersama untuk
memungkinkan penskalaan item yang responsif dalam FlowRow
(atau FlowColumn
).
Anda juga dapat membuat petak bergantian dengan ukuran item yang berbeda, di mana dua item masing-masing menempati setengah lebar, dan satu item menempati lebar penuh dari kolom berikutnya:

FlowRow
dengan ukuran baris yang bergantianAnda dapat melakukannya dengan kode berikut:
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 2 ) { val itemModifier = Modifier .padding(4.dp) .height(80.dp) .clip(RoundedCornerShape(8.dp)) .background(Color.Blue) repeat(6) { item -> // if the item is the third item, don't use weight modifier, but rather fillMaxWidth if ((item + 1) % 3 == 0) { Spacer(modifier = itemModifier.fillMaxWidth()) } else { Spacer(modifier = itemModifier.weight(0.5f)) } } }
Penentuan ukuran pecahan
Dengan Modifier.fillMaxWidth(fraction)
, Anda dapat menentukan ukuran
penampung yang harus digunakan oleh item. Hal ini berbeda dengan cara kerja Modifier.fillMaxWidth(fraction)
saat diterapkan ke Row
atau Column
, karena item Row/Column
menggunakan persentase lebar yang tersisa, bukan lebar seluruh penampung.
Misalnya, kode berikut menghasilkan hasil yang berbeda saat menggunakan FlowRow
vs Row
:
FlowRow( modifier = Modifier.padding(4.dp), horizontalArrangement = Arrangement.spacedBy(4.dp), maxItemsInEachRow = 3 ) { val itemModifier = Modifier .clip(RoundedCornerShape(8.dp)) Box( modifier = itemModifier .height(200.dp) .width(60.dp) .background(Color.Red) ) Box( modifier = itemModifier .height(200.dp) .fillMaxWidth(0.7f) .background(Color.Blue) ) Box( modifier = itemModifier .height(200.dp) .weight(1f) .background(Color.Magenta) ) }
|
![]() |
|
![]() |
fillMaxColumnWidth()
dan fillMaxRowHeight()
Menerapkan Modifier.fillMaxColumnWidth()
atau
Modifier.fillMaxRowHeight()
ke item di dalam FlowColumn
atau FlowRow
memastikan bahwa item dalam kolom atau baris yang sama memiliki lebar atau tinggi yang sama dengan
item terbesar dalam kolom/baris.
Misalnya, contoh ini menggunakan FlowColumn
untuk menampilkan daftar makanan penutup Android. Anda dapat melihat perbedaan lebar setiap item saat
Modifier.fillMaxColumnWidth()
diterapkan ke item dibandingkan saat tidak diterapkan dan
item di-wrap.
FlowColumn( Modifier .padding(20.dp) .fillMaxHeight() .fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp), maxItemsInEachColumn = 5, ) { repeat(listDesserts.size) { Box( Modifier .fillMaxColumnWidth() .border(1.dp, Color.DarkGray, RoundedCornerShape(8.dp)) .padding(8.dp) ) { Text( text = listDesserts[it], fontSize = 18.sp, modifier = Modifier.padding(3.dp) ) } } }
|
![]() |
Tidak ada perubahan lebar yang ditetapkan (item yang di-wrap) |
![]() |
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Dasar-dasar tata letak Compose
- ConstraintLayout di Compose
- Tindakan editor {:#editor-actions}