ข้อจำกัดและลำดับตัวแก้ไข

ใน Compose คุณสามารถเชื่อมโยงตัวแก้ไขหลายตัวเข้าด้วยกันเพื่อเปลี่ยนรูปลักษณ์ของ Composable ได้ เชนตัวแก้ไขเหล่านี้อาจส่งผลต่อข้อจำกัดที่ส่งไปยัง Composable ซึ่งกำหนดขอบเขตความกว้างและความสูง

หน้านี้อธิบายว่าตัวแก้ไขที่เชื่อมโยงกันส่งผลต่อข้อจำกัดอย่างไร และส่งผลต่อการวัดและการวาง Composable อย่างไร

ตัวปรับแต่งในทรี UI

หากต้องการทำความเข้าใจว่าตัวแก้ไขมีอิทธิพลต่อกันอย่างไร คุณควรเห็นภาพว่าตัวแก้ไข ปรากฏในโครงสร้าง UI อย่างไร ซึ่งสร้างขึ้นในระหว่างเฟสการจัดองค์ประกอบ ดูข้อมูลเพิ่มเติมได้ที่ส่วนการเรียบเรียง

ในโครงสร้าง UI คุณสามารถแสดงภาพตัวแก้ไขเป็นโหนด Wrapper สำหรับโหนดเลย์เอาต์ได้โดยทำดังนี้

โค้ดสำหรับ Composable และตัวแก้ไข รวมถึงการแสดงภาพเป็นแผนผัง UI
รูปที่ 1 ตัวแก้ไขที่ห่อหุ้มโหนดเลย์เอาต์ในทรี UI

การเพิ่มตัวแก้ไขมากกว่า 1 รายการลงใน Composable จะสร้างห่วงโซ่ของตัวแก้ไข เมื่อ คุณเชื่อมโยงตัวแก้ไขหลายรายการ โหนดตัวแก้ไขแต่ละรายการจะครอบคลุมส่วนที่เหลือของเชน และโหนดเลย์เอาต์ภายใน เช่น เมื่อเชื่อมโยงตัวแก้ไข clip กับตัวแก้ไข size โหนดตัวแก้ไข clip จะครอบโหนดตัวแก้ไข size ซึ่งจะครอบโหนดเลย์เอาต์ Image

ในระยะเลย์เอาต์ อัลกอริทึมที่เดินผ่านโครงสร้างจะยังคงเหมือนเดิม แต่ จะมีการเข้าชมโหนดตัวแก้ไขแต่ละรายการด้วย ด้วยวิธีนี้ ตัวแก้ไขจะเปลี่ยนข้อกำหนดด้านขนาด และตำแหน่งของตัวแก้ไขหรือโหนดเลย์เอาต์ที่ตัวแก้ไขครอบได้

ดังที่แสดงในรูปที่ 2 การใช้งาน Composable Image และ Text ประกอบด้วยเชนของตัวแก้ไขที่ครอบโหนดเลย์เอาต์เดียว การใช้งาน Row และ Column เป็นเพียงโหนดเลย์เอาต์ที่อธิบายวิธี จัดวางองค์ประกอบย่อย

โครงสร้างแบบต้นไม้จากก่อนหน้านี้ แต่ตอนนี้แต่ละโหนดเป็นเพียงเลย์เอาต์ที่เรียบง่าย โดยมีโหนดการตัดแต่งจำนวนมากที่ห่อหุ้มอยู่รอบๆ
รูปที่ 2 โครงสร้างต้นไม้แบบเดียวกับในรูปที่ 1 แต่มี Composable ใน แผนผัง UI ที่แสดงเป็นเชนของตัวแก้ไข

โดยสรุป

  • ตัวแก้ไขจะครอบโหนดตัวแก้ไขหรือเลย์เอาต์เดียว
  • โหนดเลย์เอาต์สามารถวางโหนดลูกหลายโหนดได้

ส่วนต่อไปนี้จะอธิบายวิธีใช้โมเดลความคิดนี้เพื่อหาเหตุผลเกี่ยวกับการเชื่อมโยงตัวแก้ไขและวิธีที่โมเดลความคิดนี้มีอิทธิพลต่อขนาดของ Composable

ข้อจำกัดในระยะเลย์เอาต์

ระยะเลย์เอาต์ใช้อัลกอริทึม 3 ขั้นตอนเพื่อค้นหาความกว้าง ความสูง และพิกัด x, y ของแต่ละโหนดเลย์เอาต์

  1. วัดขนาดขององค์ประกอบย่อย: โหนดจะวัดขนาดขององค์ประกอบย่อย (หากมี)
  2. กำหนดขนาดเอง: โหนดจะกำหนดขนาดของตัวเองตามการวัดเหล่านั้น
  3. วางตำแหน่งองค์ประกอบย่อย: โหนดย่อยแต่ละโหนดจะวางตำแหน่งเทียบกับตำแหน่งของโหนดเอง

Constraints ช่วยค้นหาขนาดที่เหมาะสมสำหรับโหนดใน 2 ขั้นตอนแรก ของอัลกอริทึม ข้อจำกัดจะกำหนดขอบเขตต่ำสุดและสูงสุดสำหรับความกว้างและความสูงของโหนด เมื่อโหนดตัดสินใจเกี่ยวกับขนาดของตัวเอง ขนาดที่วัดได้ ควรอยู่ในช่วงขนาดนี้

ประเภทของข้อจำกัด

ข้อจำกัดอาจเป็นอย่างใดอย่างหนึ่งต่อไปนี้

  • มีขอบเขต: โหนดมีความกว้างและความสูงสูงสุดและต่ำสุด
ข้อจำกัดที่กำหนดขอบเขตของขนาดต่างๆ ภายในคอนเทนเนอร์
รูปที่ 3 ข้อจำกัดที่มีขอบเขต
  • ไม่จำกัด: โหนดไม่มีข้อจำกัดด้านขนาด ขอบเขตความกว้างและความสูงสูงสุดจะตั้งค่าเป็นอนันต์
ข้อจำกัดที่ไม่จำกัดซึ่งตั้งค่าความกว้างและความสูงเป็นอนันต์ ข้อจำกัดไม่ได้มีแค่ในคอนเทนเนอร์
รูปที่ 4 ข้อจำกัดที่ไม่จำกัด
  • แน่นอน: ระบบจะขอให้โหนดปฏิบัติตามข้อกำหนดด้านขนาดที่แน่นอน กำหนดขอบเขตต่ำสุด และสูงสุดเป็นค่าเดียวกัน
ข้อจำกัดที่แน่นอนซึ่งเป็นไปตามข้อกำหนดด้านขนาดที่แน่นอนภายในคอนเทนเนอร์
รูปที่ 5 ข้อจำกัดที่แน่นอน
  • การรวม: โหนดเป็นไปตามข้อจำกัดประเภทต่างๆ ข้างต้นรวมกัน เช่น ข้อจำกัดอาจกำหนดขอบเขตความกว้างในขณะที่อนุญาตความสูงสูงสุดแบบไม่จำกัด หรือกำหนดความกว้างที่แน่นอนแต่กำหนดขอบเขตความสูง
คอนเทนเนอร์ 2 รายการที่แสดงชุดค่าผสมของข้อจํากัดแบบมีขอบเขตและไม่มีขอบเขต รวมถึงความกว้างและความสูงที่แน่นอน
รูปที่ 6 ชุดค่าผสมของข้อจำกัดแบบมีขอบเขตและไม่มีขอบเขต รวมถึงความกว้าง และความสูงที่แน่นอน

ส่วนถัดไปจะอธิบายวิธีส่งข้อจำกัดเหล่านี้จากองค์ประกอบหลักไปยังองค์ประกอบย่อย

วิธีส่งข้อจำกัดจากองค์กรระดับบนสุดไปยังองค์กรย่อย

ในขั้นตอนแรกของอัลกอริทึมที่อธิบายไว้ในข้อจำกัดในเลย์เอาต์ เฟส ข้อจำกัดจะส่งต่อจากองค์ประกอบหลักไปยังองค์ประกอบย่อย ในโครงสร้าง UI

เมื่อโหนดหลักวัดขนาดของโหนดย่อย โหนดหลักจะระบุข้อจำกัดเหล่านี้ให้กับโหนดย่อยแต่ละรายการเพื่อแจ้งให้ทราบว่าโหนดย่อยมีขนาดใหญ่หรือเล็กได้เพียงใด จากนั้นเมื่อกำหนดขนาดของตัวเองแล้ว ก็จะยึดตามข้อจำกัดที่ส่งมาจากองค์ประกอบระดับบนสุดของตัวเองด้วย

ในระดับสูง อัลกอริทึมจะทำงานดังนี้

  1. เพื่อกำหนดขนาดที่ต้องการใช้จริง โหนดรูทในแผนผัง UI จะวัดขนาดของโหนดลูกและส่งต่อข้อจำกัดเดียวกันไปยังโหนดลูกตัวแรก
  2. หากเป็นตัวแก้ไขที่ไม่มีผลต่อการวัดผล ระบบจะส่งต่อข้อจำกัดไปยังตัวแก้ไขถัดไป ระบบจะส่งข้อจํากัดลงในเชนตัวแก้ไขตามเดิม เว้นแต่จะพบตัวแก้ไขที่ส่งผลต่อการวัดผล จากนั้นระบบจะปรับขนาด ข้อจำกัดอีกครั้งตามความเหมาะสม
  3. เมื่อไปถึงโหนดที่ไม่มีโหนดลูก (เรียกว่า "โหนดใบ" ) โหนดนั้นจะกำหนดขนาดตามข้อจำกัดที่ส่งเข้ามา และ ส่งคืนขนาดที่กำหนดนี้ไปยังโหนดแม่
  4. โดยองค์ประกอบหลักจะปรับข้อจำกัดตามการวัดขององค์ประกอบย่อยนี้ และ เรียกองค์ประกอบย่อยถัดไปโดยใช้ข้อจำกัดที่ปรับแล้วเหล่านี้
  5. เมื่อวัดขนาดขององค์กรย่อยทั้งหมดขององค์กรระดับบนแล้ว โหนดระดับบนจะกำหนดขนาดของตัวเอง และสื่อสารขนาดดังกล่าวกับองค์กรระดับบนของตัวเอง
  6. วิธีนี้จะทำให้ระบบข้ามทั้งต้นไม้แบบ Depth-First ในที่สุดโหนดทั้งหมด ก็ตัดสินใจเกี่ยวกับขนาดของตนเอง และขั้นตอนการวัดผลก็เสร็จสมบูรณ์

ดูตัวอย่างแบบเจาะลึกได้ในวิดีโอข้อจำกัดและลำดับตัวแก้ไข

ตัวแก้ไขที่มีผลต่อข้อจำกัด

ในส่วนก่อนหน้า คุณได้เรียนรู้ว่าตัวแก้ไขบางตัวอาจส่งผลต่อขนาดข้อจำกัด ส่วนต่อไปนี้จะอธิบายตัวแก้ไขที่เฉพาะเจาะจงซึ่งส่งผลต่อ ข้อจำกัด

size ตัวปรับ

ตัวแก้ไข size จะประกาศขนาดที่ต้องการของเนื้อหา

ตัวอย่างเช่น ควรแสดงผลโครงสร้าง UI ต่อไปนี้ในคอนเทนเนอร์ของ 300dp โดย 200dp ข้อจำกัดมีขอบเขตที่อนุญาตให้ความกว้างอยู่ระหว่าง 100dp ถึง 300dp และความสูงอยู่ระหว่าง 100dp ถึง 200dp

ส่วนหนึ่งของแผนผัง UI ที่มีตัวแก้ไขขนาดซึ่งครอบโหนดเลย์เอาต์ และการแสดงข้อจำกัดที่กำหนดโดยตัวแก้ไขขนาดในคอนเทนเนอร์
รูปที่ 7 ข้อจำกัดที่กำหนดขอบเขตในโครงสร้าง UI และการแสดงในคอนเทนเนอร์

ตัวแก้ไข size จะปรับข้อจำกัดขาเข้าให้ตรงกับค่าที่ส่งไปยังตัวแก้ไข ในตัวอย่างนี้ ค่าคือ 150dp

เช่นเดียวกับรูปที่ 7 ยกเว้นตัวปรับขนาดที่ปรับข้อจำกัดขาเข้าให้ตรงกับค่าที่ส่งไปยังตัวปรับขนาด
รูปที่ 8 size ตัวปรับที่ปรับข้อจำกัดเป็น 150dp

หากความกว้างและความสูงเล็กกว่าขอบเขตข้อจำกัดที่เล็กที่สุด หรือ ใหญ่กว่าขอบเขตข้อจำกัดที่ใหญ่ที่สุด ตัวปรับแต่งจะจับคู่ข้อจำกัดที่ส่งมา ให้ใกล้เคียงที่สุดในขณะที่ยังคงปฏิบัติตามข้อจำกัดที่ส่งมา ใน

โครงสร้าง UI 2 รายการและการแสดงผลที่เกี่ยวข้องในคอนเทนเนอร์ ในกรณีแรก ตัวแก้ไขขนาดจะยอมรับข้อจำกัดที่เข้ามา ส่วนในกรณีที่สอง ตัวแก้ไขขนาดจะปรับให้เข้ากับข้อจำกัดที่ใหญ่เกินไปให้ได้มากที่สุด ซึ่งส่งผลให้เกิดข้อจำกัดที่เติมเต็มคอนเทนเนอร์
รูปที่ 9 size ตัวแก้ไขที่ยึดตามข้อจำกัดที่ส่งมาอย่างใกล้ชิดที่สุด

โปรดทราบว่าการเชื่อมต่อตัวแก้ไขหลายตัวsizeใช้ไม่ได้ ตัวแก้ไข size ตัวแรกจะกำหนดข้อจำกัดทั้งขั้นต่ำและขั้นสูงสุดเป็นค่าคงที่ แม้ว่าตัวแก้ไขขนาดที่ 2 จะขอขนาดที่เล็กหรือใหญ่กว่า แต่ก็ยังคงต้อง ยึดตามขอบเขตที่แน่นอนที่ส่งมา จึงจะไม่ลบล้างค่าเหล่านั้น

การเชื่อมโยงตัวปรับขนาด 2 รายการในแผนผัง UI และการแสดงในคอนเทนเนอร์
  ซึ่งเป็นผลลัพธ์ของค่าแรกที่ส่งผ่านเข้ามา ไม่ใช่ค่าที่ 2
รูปที่ 10 เชนของตัวแก้ไข 2 รายการ size ซึ่งค่าที่ 2 ที่ส่งผ่าน เข้ามา (50dp) จะไม่ลบล้างค่าแรก (100dp)

requiredSize ตัวปรับ

ใช้ตัวแก้ไข requiredSize แทน size หากต้องการให้ โหนดลบล้างข้อจำกัดขาเข้า ตัวแก้ไข requiredSize จะแทนที่ข้อจำกัดขาเข้า และส่งขนาดที่คุณระบุเป็นขอบเขตที่แน่นอน

เมื่อส่งขนาดกลับขึ้นไปในโครงสร้างแล้ว โหนดลูกจะอยู่ตรงกลาง พื้นที่ว่าง

ตัวแก้ไขขนาดและ requiredSize ที่เชื่อมโยงในโครงสร้าง UI และการแสดงผลที่เกี่ยวข้องในคอนเทนเนอร์ ข้อจำกัดของตัวแก้ไข requiredSize จะลบล้างข้อจำกัดของตัวแก้ไขขนาด
รูปที่ 11 ตัวแก้ไข requiredSize จะลบล้างข้อจำกัดขาเข้าจาก ตัวแก้ไข size

ตัวแก้ไข width และ height

ตัวแก้ไข size จะปรับทั้งความกว้างและความสูงของข้อจำกัด เมื่อใช้ตัวแก้ไข width คุณจะตั้งค่าความกว้างคงที่ได้ แต่ยังไม่กำหนดความสูง ในทำนองเดียวกัน คุณสามารถใช้heightตัวปรับเพื่อกำหนดความสูงคงที่ แต่ปล่อยให้ความกว้างไม่แน่นอนได้โดยทำดังนี้

ต้นไม้ UI 2 ต้น ต้นหนึ่งมีตัวแก้ไขความกว้างและการแสดงคอนเทนเนอร์ และอีกต้นหนึ่ง
  มีตัวแก้ไขความสูงและการแสดง
รูปที่ 12 width ตัวแก้ไขและheight ตัวแก้ไขที่ตั้งค่าความกว้าง และความสูงคงที่ตามลำดับ

sizeIn ตัวปรับ

ตัวแก้ไข sizeIn ช่วยให้คุณตั้งค่าข้อจำกัดขั้นต่ำและสูงสุดที่แน่นอน สำหรับความกว้างและความสูงได้ ใช้ตัวแก้ไข sizeIn หากต้องการควบคุมข้อจำกัดแบบละเอียด

แผนผัง UI ที่มีตัวแก้ไข sizeIn พร้อมตั้งค่าความกว้างและความสูงขั้นต่ำและสูงสุด
  และการแสดงผลภายในคอนเทนเนอร์
รูปที่ 13 sizeIn ตัวแก้ไขที่มี minWidth, maxWidth, minHeight และ maxHeight ตั้งค่า

ตัวอย่าง

ส่วนนี้แสดงและอธิบายเอาต์พุตจากข้อมูลโค้ดหลายรายการที่มี ตัวแก้ไขที่เชื่อมโยงกัน

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .size(50.dp)
)

ข้อมูลโค้ดนี้จะสร้างเอาต์พุตต่อไปนี้

  • ตัวปรับแต่ง fillMaxSize จะเปลี่ยนข้อจำกัดเพื่อกำหนดทั้งความกว้างและความสูงขั้นต่ำเป็นค่าสูงสุด ซึ่งก็คือ 300dp ในความกว้างและ 200dp ในความสูง
  • แม้ว่าตัวแก้ไข size จะต้องการใช้ขนาด 50dp แต่ก็ยังต้อง ปฏิบัติตามข้อจำกัดขั้นต่ำที่เข้ามา ดังนั้นตัวปรับ size จะแสดงขอบเขตข้อจำกัดที่แน่นอนของ 300 โดย 200 ด้วย ซึ่งจะ ไม่สนใจค่าที่ระบุในตัวปรับ size
  • Image จะทำตามขอบเขตเหล่านี้และรายงานขนาด 300 x 200 ซึ่ง จะส่งต่อขึ้นไปตามโครงสร้างทั้งหมด

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .wrapContentSize()
        .size(50.dp)
)

ข้อมูลโค้ดนี้จะสร้างเอาต์พุตต่อไปนี้

  • fillMaxSize ตัวปรับจะปรับข้อจำกัดเพื่อตั้งค่าทั้งความกว้างและความสูงขั้นต่ำเป็นค่าสูงสุด ซึ่งก็คือ 300dp ในความกว้าง และ 200dp ในความสูง
  • ตัวแก้ไข wrapContentSize จะรีเซ็ตข้อจำกัดขั้นต่ำ ดังนั้นในขณะที่ fillMaxSizeส่งผลให้เกิดข้อจำกัดที่แน่นอน wrapContentSize จะรีเซ็ตกลับ เป็นข้อจำกัดแบบมีขอบเขต ตอนนี้โหนดต่อไปนี้สามารถใช้พื้นที่ทั้งหมด อีกครั้ง หรือมีขนาดเล็กกว่าพื้นที่ทั้งหมดก็ได้
  • size ตัวแก้ไขจะกำหนดข้อจำกัดเป็นขอบเขตต่ำสุดและสูงสุดของ 50
  • Image จะเปลี่ยนเป็นขนาด 50 x 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 เป็นไปตามข้อจํากัดเหล่านั้นและรายงานขนาด 100 โดย 100dp
    • ตัวแก้ไข padding จะเพิ่ม 10dp ในทุกขนาด จึงเพิ่มความกว้างและความสูงที่รายงานขึ้น 20dp
    • ตอนนี้ในระยะการวาดภาพ แป้นกดร่วม clip จะทำงานบน Canvas ขนาด 120 x 120dp ดังนั้นจึงสร้างมาสก์วงกลมขนาดนั้น
    • จากนั้นตัวแก้ไข padding จะแทรกเนื้อหาโดย 10dp ในทุกขนาด ดังนั้นจึงลดขนาด Canvas เป็น 100 โดย 100dp
    • ระบบจะวาด Image ใน Canvas นั้น ระบบจะครอบตัดรูปภาพตามวงกลมเดิมของ 120dp ผลลัพธ์จึงเป็นรูปภาพที่ไม่กลม