รองรับหน้าจอรอยบาก

ลองใช้วิธีแบบ Compose
Jetpack Compose เป็นชุดเครื่องมือ UI ที่แนะนำสำหรับ Android ดูวิธีทำงานกับคัตเอาต์ของจอแสดงผลใน Compose

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

Android รองรับรอยบากบนหน้าจอในอุปกรณ์ที่ใช้ Android 9 (ระดับ API 28) ขึ้นไป อย่างไรก็ตาม ผู้ผลิตอุปกรณ์ยังรองรับรอยบากบนจอแสดงผลใน อุปกรณ์ที่ใช้ Android 8.1 หรือต่ำกว่าด้วย

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

รูปภาพที่แสดงตัวอย่างหน้าจอรอยบากตรงกลางด้านบน
รูปที่ 1 1 จอแสดงผล รอยบาก

เลือกวิธีที่แอปจัดการพื้นที่คัตเอาต์

หากไม่ต้องการให้เนื้อหาทับซ้อนกับพื้นที่คัตเอาต์ โดยทั่วไปแล้ว เพียงตรวจสอบว่าเนื้อหาไม่ทับซ้อนกับแถบสถานะและ แถบนำทางก็เพียงพอแล้ว หากคุณกำลังแสดงผลในพื้นที่คัตเอาต์ ให้ใช้ WindowInsetsCompat.getDisplayCutout() เพื่อดึงข้อมูลออบเจ็กต์ DisplayCutout ที่มีระยะขอบที่ปลอดภัยและกรอบล้อมสำหรับคัตเอาต์แต่ละรายการ API เหล่านี้ช่วยให้คุณตรวจสอบได้ว่าเนื้อหาของคุณทับซ้อนกับรอยบากหรือไม่ เพื่อให้คุณจัดตำแหน่งใหม่ได้หากจำเป็น

นอกจากนี้ คุณยังกำหนดได้ด้วยว่าเนื้อหาจะวางอยู่ด้านหลังพื้นที่ที่ตัดออกหรือไม่ แอตทริบิวต์เลย์เอาต์หน้าต่าง layoutInDisplayCutoutMode จะควบคุมวิธีวาดเนื้อหาในพื้นที่รอยบาก คุณตั้งค่า layoutInDisplayCutoutMode เป็นค่าใดค่าหนึ่งต่อไปนี้ได้

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT: เนื้อหาจะแสดงในพื้นที่รอยบากเมื่อหน้าจอรอยบากอยู่ในแถบระบบ มิเช่นนั้น หน้าต่างจะไม่ซ้อนทับรอยบากของจอแสดงผล เช่น เนื้อหาอาจมีแถบดำด้านบนและด้านล่างเมื่อแสดงในโหมดแนวนอน หากแอปกำหนดเป้าหมายเป็น SDK 35 ระบบจะตีความว่า ALWAYS สำหรับหน้าต่างที่ไม่ลอย
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS: อนุญาตให้เนื้อหาขยายไปยังพื้นที่คัตเอาต์ได้เสมอ หากแอปกำหนดเป้าหมายเป็น SDK 35 และทำงานบนอุปกรณ์ Android 15 โหมดนี้จะเป็นโหมดเดียวที่อนุญาตสำหรับหน้าต่างที่ไม่ลอยเพื่อให้แสดงผลแบบไร้ขอบ
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES: เนื้อหาจะแสดงในพื้นที่คัตเอาต์ทั้งในโหมดแนวตั้งและแนวนอน ห้าม ใช้กับหน้าต่างแบบลอย หากแอปกำหนดเป้าหมายเป็น SDK 35 ระบบจะตีความค่านี้เป็น ALWAYS สำหรับหน้าต่างที่ไม่ลอย
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER: เนื้อหาจะไม่แสดงในพื้นที่คัตเอาต์ หากแอปกำหนดเป้าหมายเป็น SDK 35 ระบบจะตีความค่านี้เป็น ALWAYS สำหรับหน้าต่างที่ไม่ลอย

คุณตั้งค่าโหมดการตัดออกได้ทั้งแบบเป็นโปรแกรมหรือโดยการตั้งค่าสไตล์ในกิจกรรม ตัวอย่างต่อไปนี้ กําหนดสไตล์เพื่อใช้แอตทริบิวต์ LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES กับกิจกรรม

<style name="ActivityTheme">
  <item name="android:windowLayoutInDisplayCutoutMode">
    shortEdges <!-- default, shortEdges, or never -->
  </item>
</style>

ส่วนต่อไปนี้จะอธิบายโหมดการตัดออกต่างๆ โดยละเอียด

ลักษณะการทำงานเริ่มต้น

หากแอปกำหนดเป้าหมายเป็น SDK 35 และทำงานบนอุปกรณ์ Android 15 LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS จะเป็นลักษณะการทำงานเริ่มต้น และ LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT จะตีความเป็น LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS สำหรับหน้าต่างที่ไม่ลอย

มิเช่นนั้น LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT จะเป็นค่าเริ่มต้น

แสดงผลเนื้อหาในบริเวณรอยบากขอบสั้น

หากแอปกำหนดเป้าหมายเป็น SDK 35 และทำงานบนอุปกรณ์ Android 15 ระบบจะตีความ LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES เป็น LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS สำหรับหน้าต่างที่ไม่ลอย

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

รูปภาพต่อไปนี้เป็นตัวอย่างของ LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES สำหรับอุปกรณ์ในแนวตั้ง

รูปภาพแสดงการแสดงเนื้อหาในพื้นที่คัตเอาต์ขณะอยู่ในโหมดแนวตั้ง
รูปที่ 2 การแสดงเนื้อหาในพื้นที่คัตเอาต์ ขณะอยู่ในโหมดแนวตั้ง

รูปภาพต่อไปนี้เป็นตัวอย่างของ LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES สำหรับอุปกรณ์ในแนวนอน

รูปภาพแสดงการแสดงผลเนื้อหาในพื้นที่คัตเอาต์ขณะอยู่ในโหมดแนวนอน
รูปที่ 3 การแสดงเนื้อหาในพื้นที่คัตเอาต์ ขณะอยู่ในโหมดแนวนอน

ในโหมดนี้ หน้าต่างจะขยายใต้รอยบากที่ขอบสั้นของจอแสดงผล ทั้งในแนวตั้งและแนวนอน ไม่ว่าหน้าต่างจะซ่อนแถบระบบ หรือไม่ก็ตาม

โดยรอยบากที่มุมจะถือว่าอยู่บนขอบด้านสั้น

รูปภาพแสดงอุปกรณ์ที่มีรอยบากมุม
รูปที่ 4 อุปกรณ์ที่มีรอยบากมุม

ไม่แสดงเนื้อหาในบริเวณหน้าจอรอยบาก

หากแอปกำหนดเป้าหมายเป็น SDK 35 และทำงานบนอุปกรณ์ Android 15 ระบบจะตีความ LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVERเป็น LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYSสำหรับหน้าต่างที่ไม่ลอย

LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER จะไม่อนุญาตให้หน้าต่างซ้อนทับกับพื้นที่รอยบาก

ต่อไปนี้เป็นตัวอย่างของ LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER ใน แนวตั้ง

รูปภาพแสดง LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER สำหรับแนวตั้ง
รูปที่ 5 ตัวอย่างของ LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER สำหรับโหมดภาพบุคคล

ต่อไปนี้เป็นตัวอย่างของ LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER ใน โหมดแนวนอน

รูปภาพแสดง LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER สำหรับแนวนอน
รูปที่ 6 ตัวอย่าง LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER ในโหมดแนวนอน

แนวทางปฏิบัติแนะนำสำหรับการรองรับหน้าจอรอยบาก

เมื่อทำงานกับรอยบากของจอแสดงผล ให้พิจารณาสิ่งต่อไปนี้

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

    รูปภาพแสดงเนื้อหาที่ถูกตัดที่ด้านบนเนื่องจากการตั้งค่าขอบที่ไม่เหมาะสม
    รูปที่ 7 ใช้ WindowInsetsCompat เพื่อ หลีกเลี่ยงการซ้อนทับหรือการตัดเนื้อหา
  • ใช้ View.getLocationInWindow() เพื่อกำหนดขนาดพื้นที่หน้าต่างที่แอปใช้ อย่าคิดว่าแอป ใช้ทั้งหน้าต่าง และอย่าใช้ View.getLocationOnScreen()

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

    รูปภาพแสดงเนื้อหาที่เลื่อนขึ้นและลงระหว่างการเปลี่ยน
    รูปที่ 8 ตัวอย่างเนื้อหาที่เลื่อนขึ้นและลง ระหว่างการเปลี่ยนฉาก
  • ในโหมดสมจริง ให้ระมัดระวังในการใช้พิกัดหน้าต่างเทียบกับพิกัดหน้าจอ เนื่องจากแอปของคุณไม่ได้ใช้ทั้งหน้าจอเมื่อมีแถบดำด้านบน-ล่างของภาพ เนื่องจาก จดหมายขอบดำ พิกัดจากต้นทางของหน้าจอจึงไม่เหมือนกับพิกัด จากต้นทางของหน้าต่าง คุณสามารถแปลงพิกัดหน้าจอเป็นพิกัดของมุมมองได้ตามต้องการโดยใช้ getLocationOnScreen() รูปภาพต่อไปนี้ แสดงความแตกต่างของพิกัดเมื่อเนื้อหามีแถบดำด้านบน-ล่างของภาพ

    รูปภาพที่แสดงพิกัดหน้าต่างเทียบกับพิกัดหน้าจอเมื่อเนื้อหามีแถบดำด้านบนและด้านล่าง
    รูปที่ 9 พิกัดหน้าต่างเทียบกับพิกัดหน้าจอเมื่อ เนื้อหามีแถบดำด้านบนและด้านล่าง
  • เมื่อจัดการ MotionEvent ให้ใช้ MotionEvent.getX() และ MotionEvent.getY() เพื่อหลีกเลี่ยง ปัญหาเกี่ยวกับพิกัดที่คล้ายกัน อย่าใช้ MotionEvent.getRawX() หรือ MotionEvent.getRawY()

ทดสอบการแสดงผลเนื้อหา

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

  1. เปิดใช้ตัวเลือกสำหรับนักพัฒนาแอป
  2. ในหน้าจอตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ ให้เลื่อนลงไปที่ส่วนการวาด แล้วเลือกจำลองจอแสดงผลที่มีรอยบาก
  3. เลือกประเภทการตัด

    รูปภาพแสดงวิธีจำลองหน้าจอรอยบากในโปรแกรมจำลอง
    รูปที่ 10 ตัวเลือกสำหรับนักพัฒนาแอปเพื่อทดสอบว่าเนื้อหา แสดงผลอย่างไร

แหล่งข้อมูลเพิ่มเติม