รูปแบบการเขียนเลย์เอาต์ช่วยให้คุณใช้ AlignmentLine
เพื่อสร้างบรรทัดการจัดตำแหน่งที่กำหนดเอง ซึ่งเลย์เอาต์หลักสามารถใช้เพื่อจัดตำแหน่งและจัดวางเลย์เอาต์ย่อยได้ เช่น Row
ใช้เส้นการจัดตำแหน่งที่กำหนดเองขององค์ประกอบย่อยเพื่อจัดตำแหน่งได้
เมื่อเลย์เอาต์ระบุค่าสำหรับ AlignmentLine
บางรายการ รายการหลักของเลย์เอาต์จะอ่านค่านี้ได้หลังจากการวัดโดยใช้โอเปอเรเตอร์ Placeable.get
ในอินสแตนซ์ Placeable
ที่เกี่ยวข้อง
จากนั้นผู้ปกครองจะกำหนดตำแหน่งของบุตรหลานตามตำแหน่งของ AlignmentLine
ได้
คอมโพสิชันบางอย่างใน Compose มีเส้นจัดตำแหน่งอยู่แล้ว ตัวอย่างเช่น คอมโพสิเบิล BasicText
จะแสดงเส้นจัดตำแหน่ง FirstBaseline
และ LastBaseline
ในตัวอย่างด้านล่าง LayoutModifier
ที่กำหนดเองชื่อ
firstBaselineToTop
จะอ่าน FirstBaseline
เพื่อเพิ่มการถอดหน้าใน Text
โดยเริ่มจากบรรทัดฐานแรก
รูปที่ 1 แสดงความแตกต่างระหว่างการเพิ่มระยะห่างจากขอบปกติให้กับองค์ประกอบ กับการใช้ระยะห่างจากขอบกับบรรทัดฐานขององค์ประกอบข้อความ
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)) } }
หากต้องการอ่าน FirstBaseline
ในตัวอย่าง ระบบจะใช้ placeable [FirstBaseline]
ในเฟสการวัด
สร้างเส้นการจัดตำแหน่งที่กำหนดเอง
เมื่อสร้างคอมโพสิเบิล Layout
ที่กำหนดเองหรือคอมโพสิเบิล LayoutModifier
ที่กำหนดเอง คุณสามารถระบุเส้นการจัดตำแหน่งที่กำหนดเองเพื่อให้คอมโพสิเบิลหลักอื่นๆ ใช้เส้นดังกล่าวเพื่อจัดตำแหน่งและวางคอมโพสิเบิลย่อยตามลำดับได้
Layout
ตัวอย่างต่อไปนี้แสดงคอมโพสิเบิล BarChart
ที่กําหนดเองซึ่งแสดงเส้นการจัดแนว 2 เส้น ได้แก่ MaxChartValue
และ MinChartValue
เพื่อให้คอมโพสิเบิลอื่นๆ ปรับแนวตามค่าข้อมูลสูงสุดและต่ำสุดของแผนภูมิได้ องค์ประกอบข้อความ 2 รายการ ได้แก่ Max และ Min ได้รับการจัดแนวให้อยู่ตรงกลางของเส้นจัดแนวที่กำหนดเอง
รูปที่ 2 BarChart
คอมโพสิเบิลกับข้อความที่ปรับให้สอดคล้องกับค่าข้อมูลสูงสุดและต่ำสุด
เส้นการจัดตำแหน่งที่กำหนดเองจะกำหนดเป็นตัวแปรระดับบนสุดในโปรเจ็กต์
/** * 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) })
เส้นการจัดตำแหน่งที่กำหนดเองเพื่อสร้างตัวอย่างของเราเป็นประเภท HorizontalAlignmentLine
เนื่องจากใช้เพื่อจัดตำแหน่งองค์ประกอบย่อยในแนวตั้ง ระบบจะส่งผ่านนโยบายการผสานเป็นพารามิเตอร์ในกรณีที่เลย์เอาต์หลายรายการระบุค่าสำหรับเส้นการจัดตำแหน่งเหล่านี้ เนื่องจากพิกัดระบบเลย์เอาต์ของ Compose และพิกัด Canvas
แสดงถึง [0, 0]
มุมซ้ายบนและแกน x
และ y
จะบวกลง ดังนั้นค่า MaxChartValue
จะน้อยกว่า MinChartValue
เสมอ ดังนั้น นโยบายการผสานคือ min
สำหรับเกณฑ์พื้นฐานค่าข้อมูลแผนภูมิสูงสุด และ max
สำหรับเกณฑ์พื้นฐานค่าข้อมูลแผนภูมิต่ำสุด
เมื่อสร้าง Layout
หรือ LayoutModifier
ที่กำหนดเอง ให้ระบุบรรทัดการจัดตำแหน่งที่กำหนดเองในเมธอด MeasureScope.layout
ซึ่งใช้พารามิเตอร์ 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() ) ) {} } } } } }
คอมโพสิชันหลักและรองของคอมโพสิชันนี้สามารถใช้การจัดตำแหน่งบรรทัดได้ คอมโพสิชันต่อไปนี้จะสร้างเลย์เอาต์ที่กำหนดเองซึ่งใช้พารามิเตอร์เป็นช่อง Text
2 ช่องและจุดข้อมูล และจัดแนวข้อความ 2 รายการให้สอดคล้องกับค่าข้อมูลสูงสุดและต่ำสุดของแผนภูมิ ตัวอย่างของคอมโพเนนต์นี้คือสิ่งที่แสดงในรูปที่ 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) ) } }
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- กราฟิกในเครื่องมือเขียน
- เลย์เอาต์ที่กำหนดเอง {:#custom-layouts }
- การวัดค่าในตัวในเลย์เอาต์การเขียน