Android TV 上的自定义视图辅助功能支持

虽然许多 Android TV 应用都是使用原生 Android 组件构建的,但同样重要的是要考虑第三方框架或组件的辅助功能,尤其是在使用自定义视图时。

直接与 OpenGL 或 Canvas 交互的自定义视图组件可能无法与 Talkback 和 Switch Access 等辅助功能服务很好地配合使用。

请考虑在 Talkback 打开时可能发生的一些问题

  • 辅助功能焦点(绿色矩形)可能会在您的应用中消失。
  • 辅助功能焦点可能会选择整个屏幕的边界。
  • 辅助功能焦点可能无法移动。
  • D 形方向键的四个方向键可能无效,即使您的代码正在处理它们。

如果在您的应用中观察到任何这些问题,请检查您的应用是否将其AccessibilityNodeInfo树公开给辅助功能服务。

本指南的其余部分提供了一些解决这些问题的方案和最佳实践。

D 形方向键事件被辅助功能服务使用

此问题的根本原因是关键事件被辅助功能服务使用。

D 形方向键事件使用 图 1. 描述系统在 Talkback 打开和关闭时如何工作的图表。

如图 1 所示,当 Talkback 打开时,D 形方向键事件不会传递给开发者定义的 D 形方向键处理程序。相反,辅助功能服务会接收按键事件,以便它们可以移动辅助功能焦点。由于自定义 Android 组件默认情况下不会向辅助功能服务公开其在屏幕上的位置信息,因此辅助功能服务无法移动辅助功能焦点以突出显示它们。

其他辅助功能服务也受到类似的影响:使用 Switch Access 时也可能会使用 D 形方向键事件。

由于 D 形方向键事件被提交给辅助功能服务,并且该服务不知道自定义视图中 UI 组件在哪里,因此您必须为您的应用实现AccessibilityNodeInfo 以正确转发按键事件。

向辅助功能服务公开信息

为了使用足够的信息(关于自定义视图的位置和描述)提供可访问性服务,请实现AccessibilityNodeInfo 来公开每个组件的详细信息。为了定义视图的逻辑关系,以便可访问性服务可以管理焦点,请实现 ExploreByTouchHelper,并使用 ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat) 为自定义视图设置它。

在实现ExploreByTouchHelper时,重写其四个抽象方法。

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 或阅读有关 填充可访问性事件 的更多信息。

最佳实践

示例

查阅 Android TV 的自定义视图可访问性示例,了解如何为使用自定义视图的应用添加可访问性支持的最佳实践。