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

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

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

ตัวแก้ไขในลําดับชั้น UI

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

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

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

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

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

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

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

โดยสรุป

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

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

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

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

  1. วัดผลโหนดย่อย: โหนดจะวัดผลโหนดย่อย (หากมี)
  2. กำหนดขนาดเอง: โหนดจะกำหนดขนาดของตนเองโดยอิงตามการวัดเหล่านั้น
  3. วางรายการย่อย: แต่ละโหนดย่อยจะวางตามตำแหน่งของโหนดนั้นๆ

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

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

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

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

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

วิธีส่งข้อจำกัดจากรายการหลักไปยังรายการย่อย

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

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

อัลกอริทึมจะทํางานในระดับสูงในลักษณะต่อไปนี้

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

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

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

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

ตัวปรับ 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 อนุกรมตัวแก้ไข size 2 รายการ ซึ่งค่าที่ 2 ที่ส่งเข้ามา (50dp) ไม่ได้ลบล้างค่าแรก (100dp)

ตัวปรับ requiredSize

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

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

ตัวแก้ไข size และ requiredSize ที่ลิงก์กันในต้นไม้ UI และการนําเสนอที่สอดคล้องกันในคอนเทนเนอร์ ข้อจำกัดของตัวแก้ไข requiredSize จะลบล้างข้อจำกัดของตัวแก้ไข size
รูปที่ 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 รายการ

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