ConstraintLayout
เป็นเลย์เอาต์ที่ให้คุณวาง Composable เทียบกับ
Composable อื่นๆ บนหน้าจอ เป็นอีกทางเลือกหนึ่งแทนที่จะใช้การซ้อนหลายระดับ
Row
, Column
, Box
และองค์ประกอบการออกแบบที่กำหนดเองอื่นๆ ConstraintLayout
มีประโยชน์เมื่อใช้เลย์เอาต์ขนาดใหญ่ที่มีข้อกำหนดการจัดตำแหน่งที่ซับซ้อนมากขึ้น
พิจารณาใช้ ConstraintLayout
ในสถานการณ์ต่อไปนี้
- เพื่อหลีกเลี่ยงการฝัง
Column
และRow
หลายรายการเพื่อวางตำแหน่งองค์ประกอบบนหน้าจอเพื่อปรับปรุงความอ่านง่ายของโค้ด - เพื่อวางองค์ประกอบคอมโพสพอยต์ให้สัมพันธ์กับองค์ประกอบคอมโพสพอยต์อื่นๆ หรือวางองค์ประกอบคอมโพสพอยต์ตามเส้นกํากับ สิ่งกีดขวาง หรือเชน
ในระบบมุมมอง ConstraintLayout
เป็นวิธีที่แนะนำในการสร้างเลย์เอาต์ขนาดใหญ่และซับซ้อน เนื่องจากลําดับชั้นมุมมองแบบแบนมีประสิทธิภาพดีกว่ามุมมองที่ฝัง แต่ข้อกังวลนี้ไม่มีใน Compose ซึ่งจัดการลําดับชั้นเลย์เอาต์แบบลําลึกได้อย่างมีประสิทธิภาพ
เริ่มต้นใช้งาน ConstraintLayout
หากต้องการใช้ ConstraintLayout
ใน Compose คุณต้องเพิ่มทรัพยากร Dependency นี้ใน
build.gradle
(นอกเหนือจาก
การตั้งค่าการเขียน)
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
ConstraintLayout
ในเครื่องมือเขียนจะทํางานด้วยวิธีต่อไปนี้โดยใช้ DSL
- สร้างการอ้างอิงสำหรับคอมโพสิเบิลแต่ละรายการใน
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
ด้วย
API ที่แยกส่วน
ในตัวอย่าง ConstraintLayout
ระบุข้อจำกัดในบรรทัดโดยมีตัวปรับใน Composable
ด้วย อย่างไรก็ตาม ก็มีบางกรณีที่ควรแยกข้อจำกัดออกจากเลย์เอาต์ที่ใช้ เช่น คุณอาจต้องการเปลี่ยนข้อจำกัดตามการกำหนดค่าหน้าจอ หรือสร้างภาพเคลื่อนไหวระหว่างชุดข้อจำกัด 2 ชุด
ในกรณีเช่นนี้ คุณสามารถใช้ ConstraintLayout
ในลักษณะอื่นได้ ดังนี้
- ส่ง
ConstraintSet
เป็นพารามิเตอร์ไปยังConstraintLayout
- กําหนดการอ้างอิงที่สร้างขึ้นใน
ConstraintSet
ให้กับคอมโพสิเบิลโดยใช้ตัวแก้ไข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
หลักเกณฑ์
หลักเกณฑ์คือตัวช่วยเล็กๆ ที่มองเห็นได้ซึ่งใช้ออกแบบเลย์เอาต์ คอมโพสิเบิลสามารถถูกจำกัดตามหลักเกณฑ์ได้ เส้นกํากับมีประโยชน์ในการวางองค์ประกอบที่ dp
หรือ percentage
ที่เจาะจงภายในคอมโพสิชันหลัก
หลักเกณฑ์มี 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()
สิ่งกีดขวาง
สิ่งกีดขวางจะอ้างอิงคอมโพสิเบิลหลายรายการเพื่อสร้างเส้นกํากับเสมือนโดยอิงตามวิดเจ็ตด้านนอกสุดของด้านที่ระบุ
หากต้องการสร้างกำแพง ให้ใช้ createTopBarrier()
(หรือ createBottomBarrier()
createEndBarrier()
, createStartBarrier()
) และระบุข้อมูลอ้างอิงที่
จะเป็นตัวกีดขวาง
ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") val topBarrier = createTopBarrier(button, text) } }
จากนั้นจะใช้อุปสรรคในบล็อก Modifier.constrainAs()
ได้
เครือ
เชนจะทำงานแบบกลุ่มในแกนเดียว (แนวนอนหรือแนวตั้ง) แกนอีกแกนหนึ่งสามารถจำกัดได้อย่างอิสระ
หากต้องการสร้างเชน ให้ใช้ 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 แรกและหลัง ComposableChainStyle.SpreadInside
: พื้นที่ทำงานจะกระจายอย่างเท่าๆ กันสำหรับองค์ประกอบทั้งหมด Composable โดยไม่มีพื้นที่ว่างก่อน Composable แรกหรือหลังจาก Composable ล่าสุดChainStyle.Packed
: พื้นที่ทำงานจะกระจายอยู่ก่อนรายการแรกและหลัง Composable ล่าสุดจะต่อกันโดยไม่มีช่องว่างระหว่าง ระหว่างกัน
ดูข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับ ConstraintLayout
ใน Compose จาก API ที่ใช้งานจริงในตัวอย่างการเขียนที่ใช้ ConstraintLayout
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- โฟกัสในการเขียน
- Kotlin สำหรับ Jetpack Compose
- ข้อมูลเบื้องต้นเกี่ยวกับเลย์เอาต์สำหรับการเขียน