ConstraintLayout
คือเลย์เอาต์ที่ช่วยให้คุณวาง Composable ที่สัมพันธ์กับ
Composable อื่นๆ บนหน้าจอได้ ซึ่งเป็นทางเลือกแทนการใช้ Row
, Column
, Box
และองค์ประกอบเลย์เอาต์ที่กำหนดเองอื่นๆ หลายรายการที่ซ้อนกัน ConstraintLayout
มีประโยชน์เมื่อใช้เลย์เอาต์ขนาดใหญ่ที่มีข้อกำหนดการจัดแนวที่ซับซ้อนมากขึ้น
พิจารณาใช้ ConstraintLayout
ในสถานการณ์ต่อไปนี้
- เพื่อหลีกเลี่ยงการซ้อน
Column
และRow
หลายรายการเพื่อจัดตำแหน่งองค์ประกอบบนหน้าจอเพื่อปรับปรุงความสามารถในการอ่านโค้ด - เพื่อวางตำแหน่ง Composable ให้สัมพันธ์กับ Composable อื่นๆ หรือวางตำแหน่ง Composable ตามแนวทาง แบร์ริเออร์ หรือเชน
ในระบบ View ConstraintLayout
เป็นวิธีที่แนะนำในการสร้างเลย์เอาต์ขนาดใหญ่
และซับซ้อน เนื่องจากลำดับชั้นของมุมมองแบบเรียบจะดีกว่ามุมมองที่ซ้อนกันในแง่ของประสิทธิภาพ
อย่างไรก็ตาม ปัญหานี้จะไม่เกิดขึ้นใน Compose ซึ่งสามารถ
จัดการลำดับชั้นของเลย์เอาต์ที่ซับซ้อนได้อย่างมีประสิทธิภาพ
เริ่มต้นใช้งาน ConstraintLayout
หากต้องการใช้ ConstraintLayout
ใน Compose คุณต้องเพิ่มการอ้างอิงนี้ใน
build.gradle
(นอกเหนือจาก
การตั้งค่า Compose)
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
ConstraintLayout
ใน Compose ทำงานด้วยวิธีต่อไปนี้โดยใช้
DSL
- สร้างการอ้างอิงสำหรับแต่ละ Composable ใน
ConstraintLayout
โดยใช้createRefs()
หรือcreateRefFor()
- ข้อจำกัดจะระบุโดยใช้ตัวแก้ไข
constrainAs()
ซึ่งใช้การอ้างอิงเป็นพารามิเตอร์และช่วยให้คุณระบุข้อจำกัดใน Lambda ของเนื้อหาได้ - ข้อจำกัดจะระบุโดยใช้
linkTo()
หรือวิธีการอื่นๆ ที่เป็นประโยชน์ parent
คือการอ้างอิงที่มีอยู่ซึ่งใช้เพื่อระบุข้อจำกัด สำหรับ ComposableConstraintLayout
เองได้
ตัวอย่าง Composable ที่ใช้ ConstraintLayout
มีดังนี้
@Composable fun ConstraintLayoutContent() { ConstraintLayout { // Create references for the composables to constrain val (button, text) = createRefs() Button( onClick = { /* Do something */ }, // Assign reference "button" to the Button composable // and constrain it to the top of the ConstraintLayout modifier = Modifier.constrainAs(button) { top.linkTo(parent.top, margin = 16.dp) } ) { Text("Button") } // Assign reference "text" to the Text composable // and constrain it to the bottom of the Button composable Text( "Text", Modifier.constrainAs(text) { top.linkTo(button.bottom, margin = 16.dp) } ) } }
โค้ดนี้จะจำกัดด้านบนของ Button
ให้กับองค์ประกอบระดับบนโดยมีระยะขอบเป็น
16.dp
และจำกัด Text
ให้กับด้านล่างของ Button
โดยมีระยะขอบเป็น
16.dp
ด้วยเช่นกัน
Decoupled API
ในConstraintLayout
ตัวอย่าง
ข้อจำกัดจะระบุในบรรทัด โดยมีตัวแก้ไขใน Composable ที่ใช้
ข้อจำกัด อย่างไรก็ตาม มีบางสถานการณ์ที่ควรแยกข้อจำกัดออกจากเลย์เอาต์ที่ใช้ เช่น คุณอาจต้องการ
เปลี่ยนข้อจำกัดตามการกำหนดค่าหน้าจอ หรือเคลื่อนไหวระหว่างชุดข้อจำกัด 2 ชุด
สำหรับกรณีเช่นนี้ คุณสามารถใช้ ConstraintLayout
ในลักษณะอื่นได้ดังนี้
- ส่ง
ConstraintSet
เป็นพารามิเตอร์ไปยังConstraintLayout
- กำหนดการอ้างอิงที่สร้างใน
ConstraintSet
ให้กับ Composable โดยใช้ตัวแก้ไขlayoutId
@Composable fun DecoupledConstraintLayout() { BoxWithConstraints { val constraints = if (minWidth < 600.dp) { decoupledConstraints(margin = 16.dp) // Portrait constraints } else { decoupledConstraints(margin = 32.dp) // Landscape constraints } ConstraintLayout(constraints) { Button( onClick = { /* Do something */ }, modifier = Modifier.layoutId("button") ) { Text("Button") } Text("Text", Modifier.layoutId("text")) } } } private fun decoupledConstraints(margin: Dp): ConstraintSet { return ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") constrain(button) { top.linkTo(parent.top, margin = margin) } constrain(text) { top.linkTo(button.bottom, margin) } } }
จากนั้นเมื่อต้องการเปลี่ยนข้อจำกัด คุณก็เพียงแค่ส่งConstraintSet
ที่แตกต่างกัน
แนวคิดของ ConstraintLayout
ConstraintLayout
มีแนวคิดต่างๆ เช่น หลักเกณฑ์ อุปสรรค และโซ่
ที่ช่วยในการจัดตำแหน่งองค์ประกอบภายใน Composable
หลักเกณฑ์
เส้นบอกแนวเป็นตัวช่วยด้านภาพขนาดเล็กที่ใช้ในการออกแบบเลย์เอาต์ Composable สามารถ
จำกัดให้เป็นแนวทางได้ แนวทางมีประโยชน์ในการจัดวางองค์ประกอบที่dp
หรือpercentage
ภายใน Composable ระดับบนสุด
เส้นไกด์มี 2 ประเภท ได้แก่ แนวตั้งและแนวนอน ส่วนเส้นแนวนอน 2 เส้นคือ top
และ bottom
และเส้นแนวตั้ง 2 เส้นคือ start
และ end
ConstraintLayout { // Create guideline from the start of the parent at 10% the width of the Composable val startGuideline = createGuidelineFromStart(0.1f) // Create guideline from the end of the parent at 10% the width of the Composable val endGuideline = createGuidelineFromEnd(0.1f) // Create guideline from 16 dp from the top of the parent val topGuideline = createGuidelineFromTop(16.dp) // Create guideline from 16 dp from the bottom of the parent val bottomGuideline = createGuidelineFromBottom(16.dp) }
หากต้องการสร้างหลักเกณฑ์ ให้ใช้ createGuidelineFrom*
พร้อมประเภทหลักเกณฑ์
ที่ต้องการ ซึ่งจะสร้างการอ้างอิงที่ใช้ในModifier.constrainAs()
บล็อกได้
อุปสรรค
Barriers อ้างอิง Composable หลายรายการเพื่อสร้างเส้นเสมือนตามวิดเจ็ตที่อยู่ด้านที่ระบุซึ่งอยู่ไกลที่สุด
หากต้องการสร้างที่กั้น ให้ใช้ createTopBarrier()
(หรือ createBottomBarrier()
,
createEndBarrier()
, createStartBarrier()
) และระบุข้อมูลอ้างอิงที่
ควรประกอบกันเป็นที่กั้น
ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") val topBarrier = createTopBarrier(button, text) } }
จากนั้นจึงใช้ Barrier ในบล็อก Modifier.constrainAs()
ได้
เชน
Chain จะให้ลักษณะการทำงานแบบกลุ่มในแกนเดียว (แนวนอนหรือแนวตั้ง) ส่วนแกนอื่นๆ จะจำกัดได้อย่างอิสระ
หากต้องการสร้างเชน ให้ใช้ createVerticalChain
หรือ createHorizontalChain
ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") val verticalChain = createVerticalChain(button, text, chainStyle = ChainStyle.Spread) val horizontalChain = createHorizontalChain(button, text) } }
จากนั้นจะใช้เชนในบล็อก Modifier.constrainAs()
ได้
คุณกำหนดค่าเชนด้วย ChainStyles
ที่แตกต่างกันได้ ซึ่งจะกำหนดวิธีจัดการ
กับพื้นที่รอบๆ คอมโพสเซเบิล เช่น
ChainStyle.Spread
: ระบบจะกระจายช่องว่างอย่างเท่าเทียมกันใน Composable ทั้งหมด รวมถึงช่องว่างก่อน Composable แรกและหลัง Composable สุดท้ายChainStyle.SpreadInside
: พื้นที่จะกระจายอย่างเท่าเทียมกันใน Composable ทั้งหมด โดยไม่มีพื้นที่ว่างก่อน Composable แรกหรือหลัง Composable สุดท้ายChainStyle.Packed
: ระบบจะเว้นวรรคก่อน Composable แรกและหลัง Composable สุดท้าย และจะรวม Composable ไว้ด้วยกันโดยไม่มีการเว้นวรรคระหว่างกัน
ดูข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับ ConstraintLayout
ใน Compose จาก API ที่ใช้งานจริงใน
ตัวอย่าง Compose ที่ใช้ ConstraintLayout
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- โฟกัสในฟีเจอร์ช่วยเขียน
- Kotlin สำหรับ Jetpack Compose
- ข้อมูลเบื้องต้นเกี่ยวกับเลย์เอาต์การเขียน