Mô hình bố cục trong Compose cho phép bạn sử dụng AlignmentLine để tạo các dòng căn chỉnh tuỳ chỉnh mà bố cục mẹ có thể dùng để căn chỉnh và đặt vị trí thành phần con cháu. Ví dụ: Row có thể dùng các dòng căn chỉnh tuỳ chỉnh của thành phần con cháu để căn chỉnh.
Khi một bố cục cung cấp một giá trị cho một AlignmentLine cụ thể, thành phần mẹ của bố cục có thể đọc giá trị này sau khi đo lường, sử dụng toán tử Placeable.get trên thực thể Placeable tương ứng. Sau đó, dựa vào vị trí của AlignmentLine, thành phần mẹ có thể quyết định vị trí của thành phần con cháu.
Một số thành phần kết hợp trong Compose đã có dòng căn chỉnh. Ví dụ: thành phần kết hợp BasicText hiển thị các dòng căn chỉnh FirstBaseline và LastBaseline.
Trong ví dụ sau, LayoutModifier tuỳ chỉnh có tên firstBaselineToTop đọc FirstBaseline để thêm khoảng đệm vào Text bắt đầu từ đường cơ sở đầu tiên.
 
    
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) } } @Preview @Composable private fun TextWithPaddingToBaseline() { MaterialTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } }
Để đọc FirstBaseline trong ví dụ, placeable [FirstBaseline] được dùng trong giai đoạn đo lường.
Tạo đường căn chỉnh tuỳ chỉnh
Khi tạo một thành phần kết hợp Layout tuỳ chỉnh hoặc một LayoutModifier tuỳ chỉnh, bạn có thể cung cấp dòng căn chỉnh tuỳ chỉnh để các thành phần kết hợp mẹ khác có thể sử dụng để căn chỉnh và định vị thành phần con cháu phù hợp.
Ví dụ sau đây thể hiện một thành phần kết hợp BarChart tuỳ chỉnh hiển thị 2 dòng căn chỉnh, MaxChartValue và MinChartValue, để các thành phần kết hợp khác có thể căn chỉnh theo giá trị dữ liệu tối đa và tối thiểu của biểu đồ. Hai thành phần văn bản, Tối đa và Tối thiểu, đã được căn chỉnh ở chính giữa các dòng căn chỉnh tuỳ chỉnh.
 
    BarChart có thể kết hợp với Văn bản được căn chỉnh theo giá trị dữ liệu tối đa và tối thiểu.Các dòng căn chỉnh tuỳ chỉnh được xác định là các biến cấp cao nhất trong dự án của bạn.
/** * AlignmentLine defined by the maximum data value in a [BarChart] */ private val MaxChartValue = HorizontalAlignmentLine(merger = { old, new -> min(old, new) }) /** * AlignmentLine defined by the minimum data value in a [BarChart] */ private val MinChartValue = HorizontalAlignmentLine(merger = { old, new -> max(old, new) })
Các dòng căn chỉnh tuỳ chỉnh để làm ví dụ thuộc loại
HorizontalAlignmentLine, được dùng để
căn chỉnh thành phần con cháu theo chiều dọc. Chính sách hợp nhất được truyền khi
một thông số trong trường hợp nhiều bố cục cung cấp một giá trị cho các dòng căn chỉnh này. Khi
toạ độ hệ thống bố cục của Compose và tọa độ Canvas
đại diện cho [0, 0], thì góc trên cùng bên trái cùng trục x và y là chiều dương hướng xuống dưới, vì vậy, giá trị MaxChartValue sẽ luôn nhỏ hơn
MinChartValue. Do đó, chính sách hợp nhất là min đối với đường cơ sở giá trị dữ liệu biểu đồ tối đa
và max đối với đường cơ sở giá trị dữ liệu biểu đồ tối thiểu.
Khi tạo Layout hoặc LayoutModifier tuỳ chỉnh, hãy chỉ định các dòng căn chỉnh tuỳ chỉnh trong phương thức MeasureScope.layout. Phương thức này sẽ có một thông số alignmentLines: Map<AlignmentLine, Int>.
@Composable private fun BarChart( dataPoints: List<Int>, modifier: Modifier = Modifier, ) { val maxValue: Float = remember(dataPoints) { dataPoints.maxOrNull()!! * 1.2f } BoxWithConstraints(modifier = modifier) { val density = LocalDensity.current with(density) { // ... // Calculate baselines val maxYBaseline = // ... val minYBaseline = // ... Layout( content = {}, modifier = Modifier.drawBehind { // ... } ) { _, constraints -> with(constraints) { layout( width = if (hasBoundedWidth) maxWidth else minWidth, height = if (hasBoundedHeight) maxHeight else minHeight, // Custom AlignmentLines are set here. These are propagated // to direct and indirect parent composables. alignmentLines = mapOf( MinChartValue to minYBaseline.roundToInt(), MaxChartValue to maxYBaseline.roundToInt() ) ) {} } } } } }
Thành phần mẹ trực tiếp và gián tiếp của thành phần kết hợp này có thể sử dụng
dòng căn chỉnh. Thành phần kết hợp sau đây tạo ra một bố cục tuỳ chỉnh có
thông số hai khe Text và các điểm dữ liệu, đồng thời sắp xếp hai văn bản này
theo giá trị dữ liệu biểu đồ tối đa và tối thiểu. Bản xem trước của thành phần kết hợp này
là nội dung biểu thị trong Hình 2.
@Composable private fun BarChartMinMax( dataPoints: List<Int>, maxText: @Composable () -> Unit, minText: @Composable () -> Unit, modifier: Modifier = Modifier, ) { Layout( content = { maxText() minText() // Set a fixed size to make the example easier to follow BarChart(dataPoints, Modifier.size(200.dp)) }, modifier = modifier ) { measurables, constraints -> check(measurables.size == 3) val placeables = measurables.map { it.measure(constraints.copy(minWidth = 0, minHeight = 0)) } val maxTextPlaceable = placeables[0] val minTextPlaceable = placeables[1] val barChartPlaceable = placeables[2] // Obtain the alignment lines from BarChart to position the Text val minValueBaseline = barChartPlaceable[MinChartValue] val maxValueBaseline = barChartPlaceable[MaxChartValue] layout(constraints.maxWidth, constraints.maxHeight) { maxTextPlaceable.placeRelative( x = 0, y = maxValueBaseline - (maxTextPlaceable.height / 2) ) minTextPlaceable.placeRelative( x = 0, y = minValueBaseline - (minTextPlaceable.height / 2) ) barChartPlaceable.placeRelative( x = max(maxTextPlaceable.width, minTextPlaceable.width) + 20, y = 0 ) } } } @Preview @Composable private fun ChartDataPreview() { MaterialTheme { BarChartMinMax( dataPoints = listOf(4, 24, 15), maxText = { Text("Max") }, minText = { Text("Min") }, modifier = Modifier.padding(24.dp) ) } }
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Đồ hoạ trong Compose
- Bố cục tuỳ chỉnh {:#custom-layouts }
- Phép đo nội tại trong bố cục Compose
