FlowRow
dan FlowColumn
adalah composable yang mirip dengan Row
dan Column
, tetapi berbeda dalam item tersebut
mengalir ke baris berikutnya saat penampung kehabisan ruang. Ini menghasilkan
beberapa baris atau kolom. Jumlah item dalam baris juga dapat dikontrol
dengan menyetel maxItemsInEachRow
atau maxItemsInEachColumn
. Anda sering 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 membangun tata letak yang
mengisi/memperluas lebar baris atau kolom saat diperlukan.
Contoh umumnya adalah untuk chip atau UI pemfilteran:
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 alur
Tata letak flow memiliki fitur dan properti berikut yang dapat Anda gunakan untuk membuat berbagai tata letak di aplikasi Anda.
Pengaturan sumbu utama: pengaturan horizontal atau vertikal
Sumbu utama adalah sumbu tempat item ditata (misalnya, dalam
FlowRow
, item disusun secara horizontal). Parameter horizontalArrangement
di FlowRow
mengontrol cara ruang kosong didistribusikan di antara item.
Tabel berikut menunjukkan contoh setelan horizontalArrangement
pada item untuk FlowRow
:
Pengaturan horizontal ditetapkan pada |
Hasil |
|
|
Untuk FlowColumn
, opsi serupa tersedia dengan verticalArrangement
, dengan
default Arrangement.Top
.
Pengaturan sumbu silang
Sumbu silang adalah sumbu yang berlawanan arah dengan sumbu utama. Misalnya, dalam FlowRow
, ini adalah sumbu vertikal. Untuk mengubah cara pengaturan keseluruhan
konten dalam penampung dalam sumbu silang, gunakan
verticalArrangement
untuk FlowRow
, dan horizontalArrangement
untuk
FlowColumn
.
Untuk FlowRow
, tabel berikut menunjukkan contoh penetapan verticalArrangement
yang berbeda
pada item:
Pengaturan vertikal ditetapkan di |
Hasil |
|
|
Untuk FlowColumn
, opsi serupa tersedia dengan horizontalArrangement
.
Pengaturan sumbu silang default adalah Arrangement.Start
.
Perataan item individual
Anda dapat memosisikan setiap item dalam baris dengan perataan
yang berbeda. 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. Perataan default adalah
Alignment.Start
.
Item maks dalam baris atau kolom
Parameter maxItemsInEachRow
atau maxItemsInEachColumn
menentukan jumlah item
maksimum di sumbu utama untuk diizinkan dalam satu baris sebelum digabungkan ke baris berikutnya. Defaultnya adalah Int.MAX_INT
, yang memungkinkan item sebanyak mungkin, selama ukurannya memungkinkan item tersebut sesuai dengan baris.
Misalnya, menyetel maxItemsInEachRow
akan memaksa tata letak awal untuk hanya
memiliki 3 item:
Tidak ada batas maksimum |
|
Item alur pemuatan lambat
ContextualFlowRow
dan ContextualFlowColumn
adalah versi
khusus dari FlowRow
dan FlowColumn
yang memungkinkan Anda memuat lambat konten
baris atau kolom flow. File ini juga memberikan informasi di sekitar posisi item (indeks, nomor baris, dan ukuran yang tersedia), seperti apakah item berada di baris pertama. Hal ini berguna untuk set data besar dan jika Anda memerlukan informasi kontekstual tentang suatu item.
Parameter maxLines
membatasi jumlah baris yang ditampilkan, dan parameter overflow
menentukan apa yang harus ditampilkan saat tambahan item
tercapai sehingga Anda dapat menentukan expandIndicator
atau
collapseIndicator
kustom.
Misalnya, untuk menampilkan tombol "+ (jumlah item yang tersisa)" atau "Tampilkan Lebih Sedikit":
val totalCount = 40 var maxLines by remember { mutableStateOf(2) } val moreOrCollapseIndicator = @Composable { scope: ContextualFlowRowOverflowScope -> val remainingItems = totalCount - scope.shownItemCount ChipItem(if (remainingItems == 0) "Less" else "+$remainingItems", onClick = { if (remainingItems == 0) { maxLines = 2 } else { maxLines += 5 } }) } ContextualFlowRow( modifier = Modifier .safeDrawingPadding() .fillMaxWidth(1f) .padding(16.dp) .wrapContentHeight(align = Alignment.Top) .verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(4.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), maxLines = maxLines, overflow = ContextualFlowRowOverflow.expandOrCollapseIndicator( minRowsToShowCollapse = 4, expandIndicator = moreOrCollapseIndicator, collapseIndicator = moreOrCollapseIndicator ), itemCount = totalCount ) { index -> ChipItem("Item $index") }
Berat item
Berat menambah item berdasarkan faktornya dan ruang yang tersedia di garis
tempatnya berada. Yang penting, ada perbedaan antara FlowRow
dan Row
terkait cara bobot digunakan untuk menghitung lebar item. Untuk Rows
, bobot
didasarkan pada semua item di 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, berat totalnya adalah 7f
. Ruang yang tersisa dalam baris atau kolom akan dibagi 7f
. Kemudian, setiap lebar item akan dihitung menggunakan: weight * (remainingSpace / totalWeight)
.
Anda dapat menggunakan kombinasi item Modifier.weight
dan max dengan FlowRow
atau
FlowColumn
untuk membuat tata letak seperti petak. Pendekatan ini berguna untuk membuat
tata letak responsif yang menyesuaikan dengan ukuran perangkat Anda.
Ada beberapa contoh tentang hal yang dapat Anda capai menggunakan bobot. Salah satu contohnya adalah petak tempat item berukuran sama, seperti yang ditunjukkan di bawah ini:
Untuk 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, item terakhir akan mengisi seluruh kolom terakhir, karena bobot total untuk seluruh baris adalah 1f
:
Anda dapat menggabungkan bobot dengan Modifiers
lain seperti
Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio)
, atau
Modifier.fillMaxWidth(fraction)
. Semua pengubah ini berfungsi bersama untuk memungkinkan ukuran item responsif dalam FlowRow
(atau FlowColumn
).
Anda juga dapat membuat petak alternatif dengan ukuran item yang berbeda, dengan masing-masing dua item berukuran setengah lebar, dan satu item menempati lebar penuh kolom berikutnya:
Anda 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)) } } }
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
menempati persentase lebar yang tersisa, bukan
lebar keseluruhan penampung.
Misalnya, kode berikut memberikan 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
akan memastikan bahwa item di kolom atau baris yang sama memiliki lebar atau tinggi yang sama dengan
item terbesar di kolom/baris.
Misalnya, contoh ini menggunakan FlowColumn
untuk menampilkan daftar makanan penutup
Android. Anda dapat melihat perbedaan lebar setiap item saat
Modifier.fillMaxColumnWidth()
diterapkan pada item dibandingkan saat tidak dan
item digabungkan.
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 (menggabungkan item) |
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Dasar-dasar tata letak Compose
- ConstraintLayout di Compose
- Tindakan editor {:#editor-actions}