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

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

รูปภาพต่อไปนี้เป็นตัวอย่างของ 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 ตัวเลือกสำหรับนักพัฒนาแอปเพื่อทดสอบ การแสดงผลเนื้อหา

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