การสนับสนุนการช่วยเหลือพิเศษเกี่ยวกับมุมมองที่กำหนดเองบน Android TV

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

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

ลองพิจารณาปัญหาบางอย่างที่อาจเกิดขึ้นเมื่อเปิด Talkback ไว้

  • โฟกัสการช่วยเหลือพิเศษ (สี่เหลี่ยมผืนผ้าสีเขียว) อาจหายไปในแอป
  • โฟกัสการช่วยเหลือพิเศษอาจเลือกขอบเขตของทั้งหน้าจอ
  • โฟกัสการช่วยเหลือพิเศษอาจเลื่อนไม่ได้
  • ปุ่ม 4 ทิศทางบน D-pad อาจไม่มีผล แม้ว่าโค้ดของคุณจะจัดการปุ่มเหล่านั้นอยู่ก็ตาม

หากพบปัญหาเหล่านี้ในแอป ให้ตรวจสอบว่าแอปแสดง AccessibilityNodeInfo ต่อบริการการช่วยเหลือพิเศษ

ส่วนที่เหลือของคู่มือนี้จะแสดงโซลูชันและแนวทางปฏิบัติแนะนำบางอย่างเพื่อแก้ไขปัญหาเหล่านี้

บริการการช่วยเหลือพิเศษใช้เหตุการณ์ D-pad

สาเหตุหลักของปัญหานี้คือบริการการช่วยเหลือพิเศษใช้เหตุการณ์สำคัญ

การใช้เหตุการณ์ Dpad และ Talkback
รูปที่ 1 แผนภาพแสดงวิธีที่ระบบทำงานเมื่อเปิดและปิด Talkback

ดังที่แสดงในรูปที่ 1 เมื่อเปิด Talkback ไว้ ระบบจะไม่ส่งเหตุการณ์ D-pad ไปยังตัวจัดการ D-pad ที่นักพัฒนาแอปกำหนดไว้ แต่บริการการช่วยเหลือพิเศษจะได้รับเหตุการณ์สำคัญเพื่อให้เลื่อนโฟกัสการช่วยเหลือพิเศษได้ เนื่องจากคอมโพเนนต์ Android ที่กำหนดเองไม่ได้แสดงข้อมูลเกี่ยวกับตำแหน่งบนหน้าจอต่อบริการการช่วยเหลือพิเศษโดยค่าเริ่มต้น บริการการช่วยเหลือพิเศษจึงไม่สามารถเลื่อนโฟกัสการช่วยเหลือพิเศษเพื่อไฮไลต์คอมโพเนนต์เหล่านั้นได้

บริการการช่วยเหลือพิเศษอื่นๆ ก็ได้รับผลกระทบในลักษณะเดียวกัน โดยระบบอาจใช้เหตุการณ์ D-pad เมื่อใช้การเข้าถึงด้วยสวิตช์ด้วย

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

แสดงข้อมูลต่อบริการการช่วยเหลือพิเศษ

หากต้องการให้ข้อมูลที่เพียงพอเกี่ยวกับตำแหน่ง และคำอธิบายของมุมมองที่กำหนดเองแก่บริการการช่วยเหลือพิเศษ ให้ใช้ AccessibilityNodeInfo เพื่อ แสดงรายละเอียดของแต่ละคอมโพเนนต์ หากต้องการกำหนดความสัมพันธ์เชิงตรรกะของมุมมอง เพื่อให้บริการการช่วยเหลือพิเศษจัดการโฟกัสได้ ให้ใช้ ExploreByTouchHelper และตั้งค่าโดยใช้ ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat) สำหรับมุมมองที่กำหนดเอง

เมื่อใช้ ExploreByTouchHelper ให้ลบล้างเมธอดนามธรรม 4 รายการ

Kotlin

// Return the virtual view ID whose view is covered by the input point (x, y).
protected fun getVirtualViewAt(x: Float, y: Float): Int

// Fill the virtual view ID list into the input parameter virtualViewIds.
protected fun getVisibleVirtualViews(virtualViewIds: List<Int>)

// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected fun onPopulateNodeForVirtualView(virtualViewId: Int, @NonNull node: AccessibilityNodeInfoCompat)

// Set the accessibility handling when perform action.
protected fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, @Nullable arguments: Bundle): Boolean

Java

// Return the virtual view ID whose view is covered by the input point (x, y).
protected int getVirtualViewAt(float x, float y)

// Fill the virtual view ID list into the input parameter virtualViewIds.
protected void getVisibleVirtualViews(List<Integer> virtualViewIds)

// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected void onPopulateNodeForVirtualView(int virtualViewId, @NonNull AccessibilityNodeInfoCompat node)

// Set the accessibility handling when perform action.
protected boolean onPerformActionForVirtualView(int virtualViewId, int action, @Nullable Bundle arguments)

ดูรายละเอียดเพิ่มเติมได้ที่ Google I/O 2013 - Enabling Blind and Low-Vision Accessibility on Android หรืออ่านเพิ่มเติมเกี่ยวกับการป้อนข้อมูลเหตุการณ์ การช่วยเหลือพิเศษ

แนวทางปฏิบัติแนะนำ

  • ต้องระบุ: AccessibilityNodeInfo.getBoundsInScreen() ต้องกำหนด ตำแหน่งของคอมโพเนนต์

  • ต้องระบุ: AccessibilityNodeInfo.setVisibleToUser() ต้องแสดง การมองเห็นของคอมโพเนนต์

  • ต้องระบุ: AccessibilityNodeInfo.getContentDescription() ต้อง ระบุคำอธิบายเนื้อหาเพื่อให้ Talkback ประกาศได้

  • ระบุ AccessibilityNodeInfo.setClassName() เพื่อให้บริการแยกแยะประเภทคอมโพเนนต์ได้

  • เมื่อใช้ performAction() ให้แสดงการดำเนินการโดยใช้ AccessibilityEvent ที่เกี่ยวข้อง

  • หากต้องการใช้ประเภทการดำเนินการเพิ่มเติม เช่น ACTION_CLICK ให้เรียกใช้ AccessibilityNodeInfo.addAction(ACTION_CLICK) โดยใช้ ตรรกะที่เกี่ยวข้องใน performAction()

  • แสดงสถานะคอมโพเนนต์สำหรับ setFocusable(), setClickable(), setScrollable() และเมธอดที่คล้ายกันเมื่อมีผล

  • อ่านเอกสารประกอบของ AccessibilityNodeInfo เพื่อระบุวิธีอื่นๆ ที่บริการการช่วยเหลือพิเศษสามารถโต้ตอบกับคอมโพเนนต์ของคุณได้ดียิ่งขึ้น

ตัวอย่าง

ดูตัวอย่างการช่วยเหลือพิเศษของมุมมองที่กำหนดเองสำหรับ Android TV เพื่อดูแนวทางปฏิบัติแนะนำ สำหรับการเพิ่มการสนับสนุนการช่วยเหลือพิเศษลงในแอปที่ใช้มุมมองที่กำหนดเอง