FlowRow và FlowColumn
là các thành phần kết hợp tương tự như Row và Column, nhưng khác ở chỗ các mục
sẽ chuyển sang dòng tiếp theo khi vùng chứa hết dung lượng. Điều này tạo ra nhiều hàng hoặc cột. Bạn cũng có thể kiểm soát số lượng mục trong một dòng bằng cách đặt maxItemsInEachRow hoặc maxItemsInEachColumn. Bạn thường có thể sử dụng FlowRow và FlowColumn để tạo bố cục thích ứng. Nội dung sẽ không bị cắt nếu các mục quá lớn đối với một chiều và việc sử dụng kết hợp maxItemsInEach* với Modifier.weight(weight) có thể giúp tạo bố cục lấp đầy/mở rộng chiều rộng của một hàng hoặc cột khi cần.
Ví dụ điển hình là đối với chip hoặc giao diện người dùng lọc:
FlowRowCách sử dụng cơ bản
Để sử dụng FlowRow hoặc FlowColumn, hãy tạo các thành phần kết hợp này và đặt các mục bên trong thành phần kết hợp đó để tuân theo quy trình chuẩn:
@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") } }
Đoạn mã này tạo ra giao diện người dùng như minh hoạ ở trên, với các mục tự động chuyển sang hàng tiếp theo khi không còn dung lượng trong hàng đầu tiên.
Tính năng của bố cục dòng chảy
Bố cục dòng chảy có các tính năng và thuộc tính sau đây mà bạn có thể sử dụng để tạo các bố cục khác nhau trong ứng dụng.
Sắp xếp trục chính: sắp xếp theo chiều ngang hoặc chiều dọc
Trục chính là trục mà các mục được bố trí (ví dụ: trong FlowRow, các mục được sắp xếp theo chiều ngang). Tham số horizontalArrangement trong FlowRow kiểm soát cách phân bổ khoảng trống giữa các mục.
Bảng sau đây cho thấy các ví dụ về cách đặt horizontalArrangement trên các mục cho FlowRow:
Đã đặt chế độ sắp xếp theo chiều ngang trên |
Kết quả |
|
|
|
|
|
|
|
|
|
|
|
Đối với FlowColumn, các lựa chọn tương tự có sẵn với verticalArrangement, với giá trị mặc định là Arrangement.Top.
Sắp xếp trục chéo
Trục chéo là trục theo hướng ngược lại với trục chính. Ví dụ: trong FlowRow, đây là trục tung. Để thay đổi cách sắp xếp nội dung tổng thể bên trong vùng chứa theo trục chéo, hãy sử dụng verticalArrangement cho FlowRow và horizontalArrangement cho FlowColumn.
Đối với FlowRow, bảng sau đây cho thấy các ví dụ về cách đặt verticalArrangement khác nhau trên các mục:
Đã đặt chế độ sắp xếp theo chiều dọc trên |
Kết quả |
|
|
|
|
|
Đối với FlowColumn, các lựa chọn tương tự có sẵn với horizontalArrangement.
Chế độ sắp xếp trục chéo mặc định là Arrangement.Start.
Căn chỉnh từng mục
Bạn có thể muốn định vị từng mục trong hàng bằng các chế độ căn chỉnh khác nhau. Chế độ này khác với verticalArrangement và horizontalArrangement vì chế độ này căn chỉnh các mục trong dòng hiện tại. Bạn có thể áp dụng chế độ này bằng Modifier.align().
Ví dụ: khi các mục trong FlowRow có chiều cao khác nhau, hàng sẽ lấy chiều cao của mục lớn nhất và áp dụng Modifier.align(alignmentOption) cho các mục:
Đã đặt chế độ căn chỉnh theo chiều dọc trên |
Kết quả |
|
|
|
|
|
Đối với FlowColumn, các lựa chọn tương tự có sẵn. Chế độ căn chỉnh mặc định là Alignment.Start.
Số lượng mục tối đa trong hàng hoặc cột
Các tham số maxItemsInEachRow hoặc maxItemsInEachColumn xác định số lượng mục tối đa trong trục chính để cho phép trong một dòng trước khi chuyển sang dòng tiếp theo. Giá trị mặc định là Int.MAX_INT, cho phép có nhiều mục nhất có thể, miễn là kích thước của các mục cho phép chúng vừa với dòng.
Ví dụ: việc đặt maxItemsInEachRow buộc bố cục ban đầu chỉ có 3 mục:
Không đặt số lượng tối đa |
|
|
|
Trọng số mục
Trọng số tăng một mục dựa trên hệ số và khoảng trống có sẵn trên dòng mà mục đó được đặt. Điều quan trọng là có sự khác biệt giữa FlowRow và Row
về cách sử dụng trọng số để tính toán chiều rộng của một mục. Đối với Rows, trọng số
dựa trên tất cả các mục trong Row. Với FlowRow, trọng số dựa trên
các mục trong dòng mà một mục được đặt chứ không phải tất cả các mục trong vùng chứa
FlowRow.
Ví dụ: nếu bạn có 4 mục đều nằm trên một dòng, mỗi mục có trọng số khác nhau là 1f, 2f, 1f và 3f, thì tổng trọng số là 7f. Khoảng trống còn lại trong một hàng hoặc cột sẽ được chia cho 7f. Sau đó, chiều rộng của mỗi mục sẽ được tính bằng cách sử dụng: weight * (remainingSpace / totalWeight).
Bạn có thể sử dụng kết hợp Modifier.weight và số lượng mục tối đa với FlowRow hoặc FlowColumn để tạo bố cục giống như lưới. Phương pháp này hữu ích để tạo bố cục thích ứng điều chỉnh theo kích thước của thiết bị.
Có một vài ví dụ khác nhau về những gì bạn có thể đạt được bằng cách sử dụng trọng số. Một ví dụ là lưới có các mục có kích thước bằng nhau, như minh hoạ dưới đây:
FlowRow để tạo lướiĐể tạo lưới có kích thước mục bằng nhau, bạn có thể làm như sau:
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) } }
Điều quan trọng là nếu bạn thêm một mục khác và lặp lại 10 lần thay vì 9 lần, thì mục cuối cùng sẽ chiếm toàn bộ cột cuối cùng, vì tổng trọng số cho toàn bộ hàng là 1f:
FlowRow để tạo lưới với mục cuối cùng chiếm toàn bộ chiều rộngBạn có thể kết hợp trọng số với các Modifiers khác như Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio) hoặc Modifier.fillMaxWidth(fraction). Tất cả các đối tượng sửa đổi này đều hoạt động cùng nhau để cho phép định cỡ thích ứng của các mục trong FlowRow (hoặc FlowColumn).
Bạn cũng có thể tạo lưới xen kẽ có kích thước mục khác nhau, trong đó 2 mục chiếm một nửa chiều rộng mỗi mục và 1 mục chiếm toàn bộ chiều rộng của cột tiếp theo:
FlowRow có kích thước xen kẽ của các hàngBạn có thể đạt được điều này bằng mã sau:
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)) } } }
Định cỡ phân đoạn
Khi sử dụng Modifier.fillMaxWidth(fraction), bạn có thể chỉ định kích thước của vùng chứa mà một mục sẽ chiếm. Điều này khác với cách
Modifier.fillMaxWidth(fraction) hoạt động khi được áp dụng cho Row hoặc Column, trong
đó các mục Row/Column chiếm một tỷ lệ phần trăm chiều rộng còn lại, thay vì
chiều rộng của toàn bộ vùng chứa.
Ví dụ: mã sau đây tạo ra các kết quả khác nhau khi sử dụng FlowRow
so với 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() và fillMaxRowHeight()
Việc áp dụng Modifier.fillMaxColumnWidth() hoặc
Modifier.fillMaxRowHeight() cho một mục bên trong FlowColumn hoặc FlowRow
đảm bảo rằng các mục trong cùng một cột hoặc hàng có cùng chiều rộng hoặc chiều cao với
mục lớn nhất trong cột/hàng.
Ví dụ: ví dụ này sử dụng FlowColumn để hiển thị danh sách các món tráng miệng trên Android. Bạn có thể thấy sự khác biệt về chiều rộng của từng mục khi Modifier.fillMaxColumnWidth() được áp dụng cho các mục so với khi không áp dụng và các mục được gói.
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) ) } } }
|
|
Không đặt thay đổi chiều rộng (các mục gói) |
|
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Kiến thức cơ bản về bố cục Compose
- ConstraintLayout trong Compose
- Các thao tác của trình chỉnh sửa {:#editor-actions}