ใน Compose องค์ประกอบ UI จะแสดงด้วยฟังก์ชันคอมโพสิเบิลที่แสดง UI บางส่วนเมื่อเรียกใช้ จากนั้นระบบจะเพิ่มลงในต้นไม้ UI ที่แสดงผลบนหน้าจอ องค์ประกอบ UI แต่ละรายการมีองค์ประกอบหลัก 1 รายการและอาจมีองค์ประกอบย่อยได้หลายรายการ องค์ประกอบแต่ละรายการยังอยู่ในองค์ประกอบหลักด้วย ซึ่งระบุเป็นตำแหน่ง (x, y) และขนาดที่ระบุเป็น width
และ height
องค์ประกอบหลักจะกำหนดข้อจำกัดสำหรับองค์ประกอบย่อย ระบบจะขอให้องค์ประกอบกำหนดขนาดภายในข้อจำกัดเหล่านั้น ข้อจำกัดจะจำกัด width
และ height
ขั้นต่ำและสูงสุดขององค์ประกอบ หากองค์ประกอบมีองค์ประกอบย่อย ระบบอาจวัดองค์ประกอบย่อยแต่ละรายการเพื่อช่วยระบุขนาดขององค์ประกอบนั้น เมื่อองค์ประกอบหนึ่งๆ กำหนดและรายงานขนาดของตัวเองแล้ว องค์ประกอบนั้นจะมีสิทธิ์กำหนดวิธีวางองค์ประกอบย่อยของตนโดยสัมพันธ์กับตัวเอง ตามที่อธิบายไว้อย่างละเอียดในการสร้างเลย์เอาต์ที่กำหนดเอง
การจัดวางโหนดแต่ละโหนดในต้นไม้ UI เป็นกระบวนการ 3 ขั้นตอน โหนดแต่ละโหนดต้องมีลักษณะดังนี้
- วัดรายการย่อย
- กำหนดขนาดของตัวเอง
- วางรายการย่อย
การใช้ขอบเขตจะกำหนดเวลาที่คุณวัดและวางตำแหน่งบุตรหลานได้
การวัดเลย์เอาต์ทำได้ในระหว่างการวัดและการวางเลย์เอาต์เท่านั้น และสามารถวางรายการย่อยได้ในระหว่างการวางเลย์เอาต์เท่านั้น (และหลังจากวัดแล้วเท่านั้น) เนื่องจากขอบเขตการคอมโพสิท เช่น MeasureScope
และ PlacementScope
ระบบจะบังคับใช้ข้อจำกัดนี้เมื่อคอมไพล์
ใช้ตัวแก้ไขเลย์เอาต์
คุณสามารถใช้ตัวแก้ไข layout
เพื่อแก้ไขวิธีวัดและวางองค์ประกอบ Layout
คือ Lambda ซึ่งพารามิเตอร์ประกอบด้วยองค์ประกอบที่วัดได้ซึ่งส่งผ่านเป็น measurable
และข้อจำกัดขาเข้าของคอมโพสิเบิลนั้นซึ่งส่งผ่านเป็น constraints
ตัวปรับแต่งเลย์เอาต์ที่กำหนดเองอาจมีลักษณะดังนี้
fun Modifier.customLayoutModifier() = layout { measurable, constraints -> // ... }
มาแสดง Text
บนหน้าจอและควบคุมระยะทางจากด้านบนถึงบรรทัดฐานของบรรทัดแรกกัน การดำเนินการนี้ตรงกับสิ่งที่ตัวแก้ไข paddingFromBaseline
ทำได้ เรากำลังนำตัวอย่างนี้ไปใช้
ซึ่งทำได้โดยใช้ตัวแก้ไข layout
เพื่อวางคอมโพสิเบิลบนหน้าจอด้วยตนเอง ลักษณะการทำงานที่ต้องการเมื่อText
ตั้งค่าระยะห่างจากขอบด้านบน24.dp
มีดังนี้
โค้ดในการสร้างการเว้นวรรคมีดังนี้
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) } }
สิ่งที่เกิดขึ้นในโค้ดดังกล่าวมีดังนี้
- ในพารามิเตอร์
measurable
lambda คุณจะวัดText
ที่แสดงโดยพารามิเตอร์ที่วัดได้โดยการเรียกใช้measurable.measure(constraints)
- คุณระบุขนาดของ Composable ได้โดยเรียกใช้
layout(width, height)
วิธี ซึ่งจะให้ Lambda ที่ใช้วางองค์ประกอบที่รวมไว้ด้วย ในกรณีนี้ ระยะห่างคือความสูงระหว่างบรรทัดฐานสุดท้ายกับระยะห่างจากขอบด้านบนที่เพิ่ม - คุณสามารถจัดตําแหน่งองค์ประกอบที่ตัดขึ้นบรรทัดใหม่บนหน้าจอได้โดยเรียกใช้
placeable.place(x, y)
หากไม่ได้วางองค์ประกอบที่ตัดขึ้นบรรทัดใหม่ องค์ประกอบเหล่านั้นจะมองไม่เห็นy
ตำแหน่งสอดคล้องกับระยะห่างจากขอบด้านบน ซึ่งเป็นตำแหน่งของบรรทัดฐานแรกในข้อความ
หากต้องการยืนยันว่าการแก้ไขนี้ทํางานตามที่คาดไว้ ให้ใช้ตัวแก้ไขนี้ใน Text
@Preview @Composable fun TextWithPaddingToBaselinePreview() { MyApplicationTheme { Text("Hi there!", Modifier.firstBaselineToTop(32.dp)) } } @Preview @Composable fun TextWithNormalPaddingPreview() { MyApplicationTheme { Text("Hi there!", Modifier.padding(top = 32.dp)) } }
สร้างเลย์เอาต์ที่กำหนดเอง
ตัวแก้ไข layout
จะเปลี่ยนเฉพาะคอมโพสิชันการโทรเท่านั้น หากต้องการวัดและจัดเลย์เอาต์คอมโพสิเบิลหลายรายการ ให้ใช้คอมโพสิเบิล Layout
แทน คอมโพสิเบิลนี้ช่วยให้คุณวัดและวางองค์ประกอบย่อยด้วยตนเองได้ เลย์เอาต์ระดับที่สูงขึ้นทั้งหมด เช่น Column
และ Row
สร้างขึ้นด้วยคอมโพสิชัน Layout
มาสร้าง Column
เวอร์ชันพื้นฐานกัน เลย์เอาต์ที่กำหนดเองส่วนใหญ่จะเป็นไปตามรูปแบบนี้
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // measure and position children given constraints logic here // ... } }
เช่นเดียวกับตัวแก้ไข layout
measurables
คือรายการของรายการย่อยที่ต้องวัด และ constraints
คือข้อจำกัดจากรายการหลัก
การใช้ MyBasicColumn
ตามตรรกะเดียวกับก่อนหน้านี้จะมีลักษณะดังนี้
@Composable fun MyBasicColumn( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( modifier = modifier, content = content ) { measurables, constraints -> // Don't constrain child views further, measure them with given constraints // List of measured children val placeables = measurables.map { measurable -> // Measure each children measurable.measure(constraints) } // Set the size of the layout as big as it can layout(constraints.maxWidth, constraints.maxHeight) { // Track the y co-ord we have placed children up to var yPosition = 0 // Place children in the parent layout placeables.forEach { placeable -> // Position item on the screen placeable.placeRelative(x = 0, y = yPosition) // Record the y co-ord placed up to yPosition += placeable.height } } } }
คอมโพสิชันย่อยถูกจํากัดด้วยข้อจํากัด Layout
(ไม่มีข้อจํากัด minHeight
) และวางตาม yPosition
ของคอมโพสิชันก่อนหน้า
วิธีใช้คอมโพสิชันที่กําหนดเองมีดังนี้
@Composable fun CallingComposable(modifier: Modifier = Modifier) { MyBasicColumn(modifier.padding(8.dp)) { Text("MyBasicColumn") Text("places items") Text("vertically.") Text("We've done it by hand!") } }
ทิศทางเลย์เอาต์
เปลี่ยนทิศทางเลย์เอาต์ของคอมโพสิเบิลโดยเปลี่ยนค่าโลคัลขององค์ประกอบ LocalLayoutDirection
หากคุณวาง Composable บนหน้าจอด้วยตนเอง LayoutDirection
จะเป็นส่วนหนึ่งของ LayoutScope
ของ Modifier layout
หรือ Composable Layout
เมื่อใช้ layoutDirection
ให้วางคอมโพสิเบิลโดยใช้ place
place
จะไม่เปลี่ยนแปลงตามทิศทางของเลย์เอาต์ (จากซ้ายไปขวาหรือจากขวาไปซ้าย) ต่างจากวิธี placeRelative
การใช้เลย์เอาต์ที่กำหนดเอง
ดูข้อมูลเพิ่มเติมเกี่ยวกับเลย์เอาต์และตัวแก้ไขได้ในหัวข้อเลย์เอาต์พื้นฐานในเครื่องมือเขียน และดูตัวอย่างการใช้งานเลย์เอาต์ที่กำหนดเองได้ในหัวข้อตัวอย่างการเขียนที่สร้างเลย์เอาต์ที่กำหนดเอง
ดูข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับเลย์เอาต์ที่กำหนดเองในเครื่องมือเขียนได้ที่แหล่งข้อมูลเพิ่มเติมต่อไปนี้
วิดีโอ
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- การวัดค่าในตัวในเลย์เอาต์การเขียน
- กราฟิกในเครื่องมือเขียน
- ตัวแก้ไขการเขียน