仅在活动场景中反应本机可访问性标识符

React Native accessibility identifiers only on active scene

TalkBack 能够从我之前浏览过的非活动场景中检测到我的 React Native 0.35.0 android 应用程序中的辅助功能标识符。如何防止这种情况,以便在识别可访问性标识符时仅使用当前场景?

例如,我让我的应用程序的第一页呈现项目的 ListView。这些与可以选择任何项目的可访问性标识符一起按预期工作。

问题是当导航到下一个页面时,一个只有一行文本的页面,在查看新场景时仍然可以访问上一个场景中的所有 ListView 项目!

我正在使用 NavigationExperimental,特别是 NavigationCardStack 进行导航。我知道 NavigationCardStack 会在堆栈中渲染每个访问过的场景,但我正在寻找一种方法,以便只能选择活动场景。

到目前为止,我已经尝试实现一个仅呈现活动场景的 NavigationExperimental 版本。虽然它解决了这个问题,但导航动画被破坏了,并且通过应用程序返回导航必须重新创建每个场景,这在我看来造成了缓慢和不可接受的体验。

虽然我不喜欢这个解决方案,但我认为在第一页的每个组件上设置 accessible={false} 可能会奏效。不幸的是,即使这样仍然可以访问文本组件。如果它有效,我可以设置 NavigationExperimental 的可访问性 属性 scene.isActive.

我能够解决这个问题。在 React Native 中有一个属性 Android 可以设置为 importantForAccessibility。它比我想要的要密集一些,但我实现了自己的 NavigationCardStack 和 NavigationCard(扩展 React Native 的版本以在渲染中添加我自己的逻辑)。

本质上,在 NavigationCardStack 中遍历每个场景时,我传递了一个新的 属性、isActiveScreen,我通过检查当前索引仅在活动场景中将其设置为 true。

然后在 NavigationCard 中,我通过添加

来利用 importantForAccessibility
importantForAccessibility={this.props.isActiveScreen ? 'yes' : 'no-hide-descendants'}

以这种方式在 android 只有我当前可见的场景启用了辅助功能,而堆栈中的所有其他场景都没有设置隐藏后代。

我在使用 react-navigation 库时遇到了同样的问题。我能够修改 react-navigation/src/views/CardStack/Card.js 为了解决这个问题,可以在此处找到,我只是修改了渲染方法(无法将代码格式化为 :()

Card.js @ Github

以下是我对此的修改:

// Fixes an issue on Android whereby talkback/voiceover will pick up elements on a child view that is not active in the stack navigator
if(this.props.scene.isActive) {
  importantForAccessibility='yes';
} else {
  importantForAccessibility='no-hide-descendants';
}

return (
  <Animated.View
    pointerEvents={pointerEvents}
    ref={this.props.onComponentRef}
    style={[styles.main, style]}
    importantForAccessibility={importantForAccessibility}
  >
    {children}
  </Animated.View>
);

此修复程序也已在 github 上分叉并发布到 NPM,如果有人需要它,如下所示: https://github.com/awseeley/react-navigation

https://www.npmjs.com/package/react-navigation-awseeley