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

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

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

ตัวแก้ไขในแผนผัง UI

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

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

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

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

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

ดังที่แสดงในรูปที่ 2 การใช้งานคอมโพสิเบิล 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. วิธีนี้เป็นการเรียกดูทั้งต้นไม้จากระดับบนสุดก่อน ในที่สุดโหนดทั้งหมดก็เลือกขนาดได้แล้ว และขั้นตอนการตรวจวัดก็เสร็จสมบูรณ์

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

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

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

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