หน้าจอรอยบากเป็นบริเวณหนึ่งในอุปกรณ์บางประเภท ที่ขยายไปถึงพื้นผิวจอแสดงผล มอบประสบการณ์การรับชมแบบไร้ขอบ และในขณะเดียวกันก็ให้พื้นที่สำหรับเซ็นเซอร์ที่สำคัญที่ด้านหน้าอุปกรณ์
Android รองรับหน้าจอรอยบากในอุปกรณ์ที่ใช้ Android 9 (API ระดับ 28) และ สูงขึ้น อย่างไรก็ตาม ผู้ผลิตอุปกรณ์ยังรองรับหน้าจอรอยบากบน อุปกรณ์ที่ใช้ Android 8.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
สำหรับอุปกรณ์ในแนวตั้ง
รูปภาพต่อไปนี้เป็นตัวอย่างของ LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
สำหรับอุปกรณ์ในแนวนอน
ในโหมดนี้ หน้าต่างจะขยายออกใต้รอยบากบนขอบด้านสั้นของจอแสดงผล ทั้งในแนวตั้งและแนวนอน ไม่ว่าหน้าต่างนั้นจะซ่อน แถบระบบ
รอยบากที่มุมจะถือว่าอยู่บนขอบสั้น
ไม่ต้องแสดงผลเนื้อหาในบริเวณหน้าจอรอยบาก
หากแอปกำหนดเป้าหมาย 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
ใน
โหมดแนวนอน:
แนวทางปฏิบัติแนะนำสำหรับการรองรับหน้าจอรอยบาก
เมื่อทำงานกับหน้าจอรอยบาก ให้พิจารณาสิ่งต่อไปนี้
- คำนึงถึงตำแหน่งองค์ประกอบที่สำคัญของ UI แต่อย่าปล่อยให้ บริเวณรอยบากจะบดบังข้อความ ตัวควบคุม หรือข้อมูลอื่นๆ ที่สำคัญ
- อย่าวางหรือขยายองค์ประกอบแบบอินเทอร์แอกทีฟที่ต้องใช้การแตะแบบละเอียด ให้จดจำบริเวณรอยบากได้ ความไวต่อการสัมผัสอาจลดลงใน บริเวณรอยบาก
หากเป็นไปได้ ให้ใช้
WindowInsetsCompat
ถึง ดึงข้อมูลความสูงของแถบสถานะและกำหนดระยะห่างจากขอบที่เหมาะสมที่จะใช้ กับเนื้อหาของคุณ หลีกเลี่ยงการฮาร์ดโค้ดความสูงของแถบสถานะเพราะอาจทำให้ เนื้อหาที่ซ้อนทับหรือถูกตัดออกใช้
View.getLocationInWindow()
เพื่อให้ทราบขนาดพื้นที่หน้าต่างที่แอปใช้อยู่ อย่าคิดเอาเองว่าแอปนี้ โดยใช้หน้าต่างทั้งหมด และอย่าView.getLocationOnScreen()
ใช้โหมดคัตเอาต์
always
,shortEdges
หรือnever
หากแอปจําเป็น เปลี่ยนเข้าและออกจากโหมดสมจริง การทำงานถูกตัดออกที่เป็นค่าเริ่มต้นอาจทำให้เกิด เนื้อหาในแอปให้แสดงผลในบริเวณคัตเอาต์ขณะที่แถบระบบอยู่ ปรากฏ แต่ไม่แสดงขณะอยู่ในโหมดสมจริง ซึ่งทำให้เนื้อหาเลื่อนขึ้น และลดลงระหว่างการเปลี่ยน ตามที่แสดงให้เห็นในตัวอย่างต่อไปนี้ในโหมดสมจริง โปรดระมัดระวังการใช้พิกัดหน้าต่างเทียบกับหน้าจอ เนื่องจาก แอปของคุณไม่ใช้ทั้งหน้าจอเมื่อมีแถบดำด้านบน-ล่างของภาพ เนื่องจาก แถบดำด้านบน-ล่างของภาพ พิกัดจากต้นทางของหน้าจอไม่เหมือนกับพิกัด จากต้นทางของหน้าต่าง คุณสามารถเปลี่ยนพิกัดของหน้าจอเป็น ตามความจำเป็นโดยใช้
getLocationOnScreen()
รูปภาพต่อไปนี้ แสดงความแตกต่างของพิกัดเมื่อเนื้อหามีแถบดำด้านบน-ล่างของภาพ:เมื่อจัดการ
MotionEvent
ให้ใช้MotionEvent.getX()
และMotionEvent.getY()
เพื่อหลีกเลี่ยง ปัญหาการประสานงานที่คล้ายกัน ไม่ใช้MotionEvent.getRawX()
หรือMotionEvent.getRawY()
ทดสอบการแสดงผลเนื้อหา
ทดสอบหน้าจอและประสบการณ์ทั้งหมดของแอป ทดสอบในอุปกรณ์ที่มี ประเภทรอยบาก หากเป็นไปได้ หากคุณไม่มีอุปกรณ์ที่มีคัตเอาต์ คุณสามารถ จำลองการกำหนดค่าคัตเอาต์ทั่วไปในอุปกรณ์หรือโปรแกรมจำลองที่ใช้ Android 9 ขึ้นไปโดยทำตามขั้นตอนต่อไปนี้
- เปิดใช้ตัวเลือกสำหรับนักพัฒนาแอป
- ในหน้าจอตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ ให้เลื่อนลงไปที่ส่วนภาพวาด และเลือกจำลองหน้าจอด้วยคัตเอาต์
เลือกประเภทคัตเอาต์
แหล่งข้อมูลเพิ่มเติม
- LAYOUT_IN_DISPLAY_CUTOUT_Mode_ALWAYS
- LAYOUT_IN_DISPLAY_CUTOUT_mode_NEVER
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGE
- LAYOUT_IN_DISPLAY_CUTOUT_mode_DEFAULT