ใน Compose คุณสามารถเชื่อมโยงตัวแก้ไขหลายรายการเข้าด้วยกันเพื่อเปลี่ยนรูปลักษณ์ของ Composable ได้ เชนตัวปรับแต่งเหล่านี้อาจส่งผลต่อข้อจำกัดที่ส่งไปยัง Composable ซึ่งกำหนดขอบเขตความกว้างและความสูง
หน้านี้อธิบายว่าตัวปรับแต่งที่เชื่อมโยงส่งผลต่อข้อจำกัดอย่างไร และส่งผลต่อการวัดและการจัดวาง Composable อย่างไร
ตัวแก้ไขในโครงสร้าง UI
เพื่อให้เข้าใจว่าตัวปรับแต่งมีอิทธิพลต่อกันอย่างไร การแสดงภาพลักษณะที่ปรากฏในโครงสร้าง UI ซึ่งสร้างขึ้นในระยะการจัดองค์ประกอบจะช่วยได้ ดูข้อมูลเพิ่มเติมได้ที่ส่วนองค์ประกอบ
ในแผนผัง UI คุณสามารถแสดงภาพตัวแก้ไขเป็นโหนด Wrapper สำหรับโหนดเลย์เอาต์ได้ ดังนี้
การเพิ่มตัวแก้ไขมากกว่า 1 รายการลงใน Composable จะสร้างเชนของตัวแก้ไข เมื่อคุณเชื่อมโยงตัวแก้ไขหลายรายการ โหนดตัวแก้ไขแต่ละโหนดจะรวมส่วนที่เหลือของเชนและโหนดเลย์เอาต์ไว้ภายใน ตัวอย่างเช่น เมื่อคุณเชื่อมโยงตัวแก้ไข clip และ size โหนดตัวแก้ไข clip จะรวมโหนดตัวแก้ไข size ซึ่งจะรวมโหนดเลย์เอาต์ Image อีกที
ในระยะเลย์เอาต์ อัลกอริทึมที่เดินตามต้นไม้จะยังคงเหมือนเดิม แต่ระบบจะเข้าชมโหนดตัวแก้ไขแต่ละโหนดด้วย ด้วยวิธีนี้ ตัวแก้ไขจะเปลี่ยนข้อกำหนดด้านขนาดและตำแหน่งของตัวแก้ไขหรือโหนดเลย์เอาต์ที่รวมอยู่ได้
ดังที่แสดงในรูปที่ 2 การติดตั้งใช้งานคอมโพสิเบิล Image และ Text ประกอบด้วยเชนของตัวแก้ไขที่รวมโหนดเลย์เอาต์เดียว
การติดตั้งใช้งาน Row และ Column เป็นโหนดเลย์เอาต์ที่อธิบายวิธีจัดเลย์เอาต์ขององค์ประกอบย่อย
สรุปได้ว่า
- ตัวแก้ไขจะรวมตัวแก้ไขหรือโหนดเลย์เอาต์รายการเดียว
- โหนดเลย์เอาต์สามารถจัดวางโหนดบุตรหลานได้หลายโหนด
ส่วนต่อไปนี้จะอธิบายวิธีใช้โมเดลทางความคิดนี้เพื่อพิจารณาเกี่ยวกับการเชื่อมโยงตัวปรับแต่งและวิธีที่ตัวปรับแต่งส่งผลต่อขนาดของ Composable
ข้อจำกัดในระยะเลย์เอาต์
ระยะเลย์เอาต์เป็นไปตามอัลกอริทึม 3 ขั้นตอนเพื่อค้นหาความกว้าง ความสูง และพิกัด x, y ของโหนดเลย์เอาต์แต่ละโหนด ดังนี้
- วัดโหนดย่อย: โหนดจะวัดโหนดย่อย (หากมี)
- กำหนดขนาดของตัวเอง: โหนดจะกำหนดขนาดของตัวเองตามการวัดเหล่านั้น
- วางโหนดบุตรหลาน: โหนดบุตรหลานแต่ละโหนดจะวางตามตำแหน่งของโหนดเอง
Constraints ช่วยค้นหาขนาดที่เหมาะสมสำหรับโหนดในระหว่าง 2 ขั้นตอนแรกของอัลกอริทึม ข้อจำกัดจะกำหนดขอบเขตต่ำสุดและสูงสุดสำหรับความกว้างและความสูงของโหนด เมื่อโหนดกำหนดขนาด ขนาดที่วัดได้ควรอยู่ในช่วงขนาดนี้
ประเภทข้อจำกัด
ข้อจำกัดอาจเป็นอย่างใดอย่างหนึ่งต่อไปนี้
- มีขอบเขต: โหนดมีความกว้างและความสูงสูงสุดและต่ำสุด
- ไม่จำกัด: โหนดไม่มีข้อจำกัดด้านขนาด ขอบเขตความกว้างและความสูงสูงสุดจะตั้งค่าเป็นไม่มีที่สิ้นสุด
- Exact: ระบบขอให้โหนดเป็นไปตามข้อกำหนดด้านขนาดที่แน่นอน ขอบเขตต่ำสุดและสูงสุดตั้งค่าเป็นค่าเดียวกัน
- แบบผสม: โหนดเป็นไปตามข้อจำกัดประเภทต่างๆ ข้างต้นรวมกัน เช่น ข้อจำกัดอาจจำกัดความกว้างในขณะที่อนุญาตให้มีความสูงสูงสุดแบบไม่จำกัด หรือกำหนดความกว้างที่แน่นอนแต่ให้ความสูงที่จำกัด
ส่วนถัดไปจะอธิบายวิธีส่งต่อข้อจำกัดเหล่านี้จากระดับบนไปยังระดับล่าง
วิธีส่งต่อข้อจำกัดจากระดับบนไปยังระดับย่อย
ในขั้นตอนแรกของอัลกอริทึมที่อธิบายไว้ในข้อจำกัดในระยะเลย์เอาต์ ระบบจะส่งข้อจำกัดจากระดับบนลงล่างในโครงสร้าง UI
เมื่อโหนดหลักวัดโหนดรอง โหนดหลักจะระบุข้อจำกัดเหล่านี้ให้กับโหนดรองแต่ละโหนดเพื่อให้ทราบว่าโหนดรองมีขนาดใหญ่หรือเล็กได้เพียงใด จากนั้นเมื่อกำหนดขนาดของตัวเอง ก็จะยึดตามข้อจำกัดที่ส่งมาจากองค์ประกอบหลักด้วย
ในระดับสูง อัลกอริทึมจะทำงานในลักษณะต่อไปนี้
- โหนดรูทในต้นไม้ UI จะวัดโหนดย่อยและส่งต่อข้อจำกัดเดียวกันไปยังโหนดย่อยแรกเพื่อตัดสินใจขนาดที่ต้องการใช้จริง
- หากองค์ประกอบย่อยเป็นตัวแก้ไขที่ไม่ส่งผลต่อการวัด ระบบจะส่งต่อข้อจำกัดไปยังตัวแก้ไขถัดไป ระบบจะส่งข้อจำกัดลงไปตามเชนของตัวแก้ไขตามที่เป็นอยู่ เว้นแต่จะถึงตัวแก้ไขที่ส่งผลต่อการวัด จากนั้นระบบจะปรับขนาดข้อจำกัดตามความเหมาะสม
- เมื่อถึงโหนดที่ไม่มีโหนดย่อย (เรียกว่า "โหนดปลายสุด") โหนดจะตัดสินใจขนาดตามข้อจำกัดที่ส่งเข้ามา และแสดงผลขนาดที่แก้ไขแล้วนี้ไปยังโหนดหลัก
- วิดเจ็ตหลักจะปรับข้อจำกัดตามการวัดของวิดเจ็ตย่อยนี้ และเรียกใช้วิดเจ็ตย่อยถัดไปโดยใช้ข้อจำกัดที่ปรับแล้วเหล่านี้
- เมื่อวัดโหนดย่อยทั้งหมดของโหนดหลักแล้ว โหนดหลักจะกำหนดขนาดของตัวเองและสื่อสารขนาดนั้นไปยังโหนดหลักของตัวเอง
- ด้วยวิธีนี้ ระบบจะข้ามผ่านทั้งต้นไม้แบบ Depth-First ในที่สุด โหนดทั้งหมดจะตัดสินใจเลือกขนาดของตนเอง และขั้นตอนการวัดขนาดจะเสร็จสมบูรณ์
ดูตัวอย่างเชิงลึกได้ในวิดีโอข้อจำกัดและลำดับของตัวแก้ไข
ตัวแก้ไขที่มีผลต่อข้อจำกัด
คุณได้เรียนรู้ในส่วนก่อนหน้าแล้วว่าตัวแก้ไขบางตัวอาจส่งผลต่อขนาดข้อจำกัด ส่วนต่อไปนี้จะอธิบายตัวแก้ไขที่เฉพาะเจาะจงซึ่งส่งผลต่อข้อจำกัด
ตัวปรับแต่ง size
ตัวแก้ไข size จะประกาศขนาดที่ต้องการของเนื้อหา
ตัวอย่างเช่น แผนผัง UI ต่อไปนี้ควรแสดงผลในคอนเทนเนอร์ขนาด 300dp คูณ 200dp ข้อจำกัดมีขอบเขต โดยอนุญาตให้มีความกว้างระหว่าง 100dp ถึง 300dp และความสูงระหว่าง 100dp ถึง 200dp ดังนี้
ตัวแก้ไข size จะปรับข้อจำกัดขาเข้าให้ตรงกับค่าที่ส่งมา
ในตัวอย่างนี้ ค่าคือ 150dp:
size กำลังปรับข้อจำกัดเป็น 150dpหากความกว้างและความสูงมีขนาดเล็กกว่าขอบเขตข้อจำกัดที่เล็กที่สุด หรือใหญ่กว่าขอบเขตข้อจำกัดที่ใหญ่ที่สุด ตัวปรับแต่งจะจับคู่ข้อจำกัดที่ส่งมาให้ใกล้เคียงที่สุดเท่าที่จะทำได้ โดยยังคงยึดตามข้อจำกัดที่ส่งมา ดังนี้
size ตัวแก้ไขที่ยึดตามข้อจำกัดที่ส่งมาอย่างใกล้เคียงที่สุดโปรดทราบว่าการเชื่อมโยงตัวแก้ไข size หลายรายการจะใช้ไม่ได้ ตัวแก้ไข size ตัวแรกจะตั้งค่าข้อจำกัดทั้งต่ำสุดและสูงสุดเป็นค่าคงที่ แม้ว่าตัวแก้ไขขนาดที่ 2 จะขอขนาดที่เล็กกว่าหรือใหญ่กว่า แต่ก็ยังต้องเป็นไปตามขอบเขตที่แน่นอนที่ส่งเข้ามา ดังนั้นจึงจะไม่ลบล้างค่าเหล่านั้น
size 2 ตัว ซึ่งค่าที่ 2 ที่ส่งเข้ามา (50dp) จะไม่ลบล้างค่าแรก (100dp)ตัวปรับแต่ง requiredSize
ใช้ตัวแก้ไข requiredSize แทน size หากต้องการให้โหนดลบล้างข้อจำกัดที่เข้ามา ตัวแก้ไข requiredSize จะแทนที่ข้อจำกัดขาเข้าและส่งขนาดที่คุณระบุเป็นขอบเขตที่แน่นอน
เมื่อส่งขนาดกลับขึ้นไปในโครงสร้าง โหนดย่อยจะอยู่ตรงกลางในพื้นที่ว่างที่มีอยู่
requiredSize จะลบล้างข้อจำกัดขาเข้าจากตัวแก้ไข sizeตัวแก้ไข width และ height
ตัวแก้ไข size จะปรับทั้งความกว้างและความสูงของข้อจำกัด ตัวแก้ไข width ช่วยให้คุณกำหนดความกว้างคงที่ได้ แต่ไม่ต้องกำหนดความสูง
ในทำนองเดียวกัน คุณสามารถใช้ตัวแก้ไข height เพื่อกำหนดความสูงคงที่ แต่ปล่อยให้ความกว้างไม่แน่นอนได้ ดังนี้
width และตัวแก้ไข height จะตั้งค่าความกว้างและความสูงคงที่ตามลำดับตัวปรับแต่ง sizeIn
ตัวแก้ไข sizeIn ช่วยให้คุณตั้งค่าข้อจำกัดขั้นต่ำและสูงสุดที่แน่นอนสำหรับความกว้างและความสูงได้ ใช้ตัวปรับแต่ง sizeIn หากต้องการควบคุมข้อจำกัดอย่างละเอียด
sizeIn ที่มี minWidth, maxWidth, minHeight และ maxHeight ตั้งค่าไว้ตัวอย่าง
ส่วนนี้จะแสดงและอธิบายเอาต์พุตจากข้อมูลโค้ดหลายรายการที่มีตัวแก้ไขแบบเชน
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
ข้อมูลโค้ดนี้จะสร้างเอาต์พุตต่อไปนี้
Image จะเติมขนาดสูงสุดตามผลลัพธ์ของเชนตัวแก้ไข- ตัวแก้ไข
fillMaxSizeจะเปลี่ยนข้อจำกัดเพื่อตั้งค่าทั้งความกว้างและความสูงขั้นต่ำเป็นค่าสูงสุด ซึ่งก็คือความกว้าง300dpและความสูง200dp - แม้ว่าตัวแก้ไข
sizeจะต้องการใช้ขนาด50dpแต่ก็ยังคงต้องปฏิบัติตามข้อจำกัดขั้นต่ำที่เข้ามา ดังนั้นตัวแก้ไขsizeจะแสดงผลขอบเขตข้อจำกัดที่แน่นอนของ300คูณ200ด้วย โดยไม่สนใจค่าที่ระบุในตัวแก้ไขsize Imageจะทำตามขอบเขตเหล่านี้และรายงานขนาด300คูณ200ซึ่งจะส่งต่อไปยังต้นไม้ทั้งหมด
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
ข้อมูลโค้ดนี้จะสร้างเอาต์พุตต่อไปนี้
Image จะอยู่ตรงกลางและมีขนาด 50dp- ตัวแก้ไข
fillMaxSizeจะปรับข้อจำกัดเพื่อตั้งค่าทั้งความกว้างและความสูงขั้นต่ำเป็นค่าสูงสุด ซึ่งก็คือความกว้าง300dpและความสูง200dp - ตัวแก้ไข
wrapContentSizeจะรีเซ็ตข้อจำกัดขั้นต่ำ ดังนั้น แม้ว่าfillMaxSizeจะส่งผลให้เกิดข้อจำกัดแบบคงที่ แต่wrapContentSizeจะรีเซ็ตกลับเป็นข้อจำกัดแบบมีขอบเขต ตอนนี้โหนดต่อไปนี้จะใช้พื้นที่ทั้งหมดอีกครั้งหรือมีขนาดเล็กกว่าพื้นที่ทั้งหมดก็ได้ - ตัวแก้ไข
sizeจะตั้งค่าข้อจำกัดเป็นขอบเขตต่ำสุดและสูงสุดของ50 Imageจะเปลี่ยนเป็นขนาด50คูณ50และตัวแก้ไขsizeจะส่งต่อขนาดนั้น- ตัวแก้ไข
wrapContentSizeมีพร็อพเพอร์ตี้พิเศษ โดยจะนำองค์ประกอบย่อยและวางไว้ตรงกลางของขอบเขตขั้นต่ำที่ใช้ได้ซึ่งส่งผ่านไปยังองค์ประกอบนั้น ขนาดที่สื่อสารกับองค์ประกอบหลักจึงเท่ากับขอบเขตขั้นต่ำที่ส่งเข้ามา
การรวมตัวแก้ไขเพียง 3 ตัวช่วยให้คุณกำหนดขนาดสำหรับ Composable และจัดให้อยู่กึ่งกลางในองค์ประกอบหลักได้
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
ข้อมูลโค้ดนี้จะสร้างเอาต์พุตต่อไปนี้
- ตัวแก้ไข
clipไม่ได้เปลี่ยนข้อจำกัด - ตัวแก้ไข
paddingจะลดข้อจำกัดสูงสุด - ตัวแก้ไข
sizeจะตั้งค่าข้อจำกัดทั้งหมดเป็น100dp Imageจะยึดตามข้อจำกัดเหล่านั้นและรายงานขนาดเป็น100dpคูณ100dp- ตัวปรับแต่ง
paddingจะเพิ่ม10dpในทุกด้านให้กับขนาดที่รายงานโดยImageดังนั้นเลย์เอาต์ที่มีระยะห่างจากขอบจะรายงานความกว้างและความสูงเป็น120dp - ตอนนี้ในขั้นตอนการวาด ตัวปรับแต่ง
clipจะทำงานบน Canvas ขนาด120dpคูณ120dpระบบจะสร้างมาสก์วงกลมขนาดดังกล่าว - จากนั้นตัวปรับแต่ง
paddingจะแทรกเนื้อหาเข้าไป10dpในทุกด้าน ซึ่งจะลดขนาด Canvas สำหรับImageเป็น100dpคูณ100dp - ระบบจะวาด
Imageในแคนวาสขนาดเล็กลงนั้น ระบบจะตัดรูปภาพตามวงกลมเดิมของ120dpดังนั้นผลลัพธ์ที่ได้จึงไม่เป็นวงกลม