以编程方式移动辅助功能焦点

Move accessibility focus programmatically

是否可以在按下按钮时将辅助功能焦点(iOS 的 VoiceOver 和 Android 的对讲)移动到定义的小部件?

我试过在 Semantics package 中搜索,但我找不到获得它的方法。

也可以让屏幕reader从头开始重新启动语义树。

我有一个 PageView,其中包含 3 个页面和要使用 PageController 移动 back/forward 的按钮。当使用按钮(调用 _pageController.animateToPage)更改时,我想将焦点移动到页面的开头。

目前无法在 Flutter 中执行此操作。输入焦点和可访问性焦点是两个不同的东西。似乎很多人都这么建议:

FocusScope.of(context).requestFocus(_myFocusNode);

问题是这只会改变输入焦点。辅助功能焦点,即 TalkBack 和 Voiceover 提供的绿色/蓝色/黑色框,不会改变。

这就是为什么您可以使用打印语句验证焦点但框没有移动的原因。

截至目前,无法更改 Flutter 中的辅助功能焦点。这是一个巨大的疏忽,也是创建真正可访问的应用程序的巨大障碍。

编辑 为了完整起见,我确实找到了一个丑陋的解决方法。

如果您将焦点更改为表单字段,例如文本字段,那么辅助功能焦点也会更新。

在我的例子中,我使用的是一个几乎没有附加任何样式的 FlatButton。显然,您随后必须使该按钮 执行 某些操作,但它至少会让您到达您想去的地方附近。

哈克?绝对可以,但是代替更好的选择,这就是我目前所拥有的。

简而言之,不,目前还没有允许您通过代码移动辅助功能焦点的方法。

参考 中的免责声明作为一些背景(尽管 Android 仍然允许我们这样做..)

DISCLAIMER: Forcing focus on Activity load to be anywhere but at the top bar is always (okay, always should almost never be said), but really, just don't do it. It is a violation of all sorts of WCAG 2.0 regulations, including 3.2.1 and 3.2.3, regarding predictable navigation and context changes respectively. You are, likely, actually making your app MORE inaccessible by doing this.

http://www.w3.org/TR/WCAG20/#consistent-behavior

Dart 团队目前坚定地支持该规则,因此添加此功能并不是优先事项。

如果您确实希望通知用户现在可以看到不同的页面,您可以在执行某些操作后使用 SemanticsService.announce() 来通知用户。例如,在 onPageChanged

中设置
onPageChanged: (int page) {
  // announce new page
}