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

ใน 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 by 200dp ข้อจำกัดมีขอบเขตที่อนุญาตให้ความกว้างอยู่ระหว่าง 100dp ถึง 300dp และความสูงอยู่ระหว่าง 100dp ถึง 200dp ดังนี้

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

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

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

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

โครงสร้าง UI 2 รายการและการแสดงผลที่เกี่ยวข้องในคอนเทนเนอร์ ในตัวอย่างแรก ตัวแก้ไขขนาดจะยอมรับข้อจำกัดที่เข้ามา ส่วนในตัวอย่างที่ 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)
)

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

สี่เหลี่ยมสีน้ำเงินที่เติมคอนเทนเนอร์ระดับบนสุด
รูปที่ 14 Image จะมีขนาดสูงสุดเป็นผลมาจากเชนตัวแก้ไข
  • ตัวปรับแต่ง 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)
)

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

สี่เหลี่ยมจัตุรัสสีน้ำเงินขนาดเล็กอยู่ตรงกลางภายในคอนเทนเนอร์ระดับบนสุด
รูปที่ 15 Image อยู่ตรงกลางและมีขนาดเท่ากับ 50dp
  • 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)
)

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

รูปร่างวงกลมที่ถูกตัดอย่างไม่ถูกต้องเนื่องจากลำดับตัวแก้ไข
รูปที่ 16 รูปร่างที่ตัดอย่างไม่ถูกต้องเนื่องจากลำดับของตัวแก้ไข
  • เครื่องแก้ไข clip จะไม่เปลี่ยนแปลงข้อจำกัด
  • ตัวแก้ไข padding จะลดข้อจำกัดสูงสุด
  • ตัวแก้ไข size จะตั้งค่าข้อจำกัดทั้งหมดเป็น 100dp
  • Image เป็นไปตามข้อจํากัดเหล่านั้นและรายงานขนาด 100dp โดย 100dp
  • padding ตัวแก้ไขจะเพิ่ม 10dp ในทุกด้านให้กับขนาดที่รายงานโดย Image ดังนั้นเลย์เอาต์ที่มีระยะห่างจึงรายงานความกว้างและความสูงเป็น 120dp
  • ตอนนี้ในขั้นตอนการวาด clip ตัวปรับแต่งจะทำงานบน Canvas ขนาด 120dp x 120dp ซึ่งจะสร้างมาสก์วงกลมที่มีขนาดดังกล่าว
  • จากนั้นตัวแก้ไข padding จะแทรกเนื้อหาโดย 10dp ในทุกด้าน ซึ่งจะ ลดขนาด Canvas สำหรับ Image เป็น 100dp โดย 100dp
  • ระบบจะวาด Image ใน Canvas ที่เล็กลงนั้น ระบบจะครอบตัดรูปภาพตาม วงกลมต้นฉบับของ 120dp ผลลัพธ์จึงเป็นรูปภาพที่ไม่กลม