Talkback 在 Android 电视上的标题之前首先宣布聚焦按钮的标签

Talkback announces focused button's label first before the title on Android TV

我正在为 Android 电视实现一个屏幕,它在左侧有一个屏幕标题和一个按钮。以及自定义列表views/rows(selectable/clickable),垂直排列,在页面右侧。

我们希望当用户看到该屏幕时,左侧的按钮处于焦点位置。为此,我在片段的 onResume() 中调用 button.requestFocus()

这破坏了可访问性。启用对讲后,首先宣布的是按钮的标签。我想要的是先公布标题,再公布按钮的标签。

我试图通过

宣布自定义文本(可能是标题)

rootView.announceForAccessibility(accessibilityText)

其中 rootView 是 xml 布局的根,accessibilityText 是需要公布的文本。

但这并没有帮助,按钮的标签获得了优先权。

我该如何解决这个问题?

我会请你考虑WCAG Guideline 3.2.1:

The intent of this Success Criterion is to ensure that functionality is predictable as visitors navigate their way through a document. Any component that is able to trigger an event when it receives focus must not change the context. Examples of changing context when a component receives focus include, but are not limited to:

  • forms submitted automatically when a component receives focus;
  • new windows launched when a component receives focus;
  • focus is changed to another component when that component receives focus; <-- emphasis here

也引自Android Accessibility Team

So something similar that people like to do is manage accessibility focus themselves. And again, this is a bad idea. accessibility focus has to be determined by the accessibility service, and just like announcements this creates an inconsistency in experience. And actually, that one of the biggest issues that accessibility users face, inconsistency, across applications and over time.

话虽如此,您可能需要考虑使用以下属性确保组件的 focus order / priority

android:nextFocusUp
android:nextFocusDown
android:nextFocusLeft
android:nextFocusRight

还要确保任何可能突出显示的组组件都设置了 importantForAccessibility 属性。

我想尝试提供更多帮助,但没有示例 XML 文件,很难了解您的特定用例。您是否尝试过使用可访问性用户测试视图布局?

我从 ATAUL MUNIM 的 this 文章中得到启发。在明确请求焦点之前,我添加了一个检查是否启用了对讲。

 protected fun isTalkBackEnabled(): Boolean {
    val a11yServices = context?.getSystemService(ACCESSIBILITY_SERVICE) as? AccessibilityManager
    return a11yServices?.isTouchExplorationEnabled?:false
}

if(isTalkBackEnabled().not()) {
   button.requestFocus()
}

这个解决方案几乎让我摆脱了我面临的问题。这也是我前进的唯一途径,因为我的应用程序的最低 API 级别是 21,这消除了使用 android:screenReaderFocusable

的选项