辅助功能
Android 和 iOS 都提供了将应用与辅助技术(如捆绑的屏幕阅读器 VoiceOver(iOS)和 TalkBack(Android))集成的 API。React Native 具有补充性 API,可让您的应用适应所有用户。
Android 和 iOS 在其方法上略有不同,因此 React Native 实现可能因平台而异。
辅助功能属性
accessible
当 true
时,表示该视图是一个辅助功能元素。当视图是辅助功能元素时,它会将其子元素组合成一个可选择的组件。默认情况下,所有可触摸元素都是可访问的。
在 Android 上,react-native View 的 accessible={true}
属性将转换为本机 focusable={true}
。
<View accessible={true}>
<Text>text one</Text>
<Text>text two</Text>
</View>
在上面的示例中,辅助功能焦点仅在具有 accessible
属性的父视图上可用,而“文本一”和“文本二”则不可用。
accessibilityLabel
当视图被标记为可访问时,建议在视图上设置 accessibilityLabel
,以便使用 VoiceOver 或 TalkBack 的用户知道他们选择了哪个元素。当选择关联的元素时,屏幕阅读器会将此字符串口述出来。
要使用,请在您的 View、Text 或 Touchable 上将 accessibilityLabel
属性设置为自定义字符串。
<TouchableOpacity
accessible={true}
accessibilityLabel="Tap me!"
onPress={onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableOpacity>
在上面的示例中,TouchableOpacity 元素上的 accessibilityLabel
将默认为“按我!”。该标签是通过将所有 Text 节点子元素用空格分隔连接起来构建的。
accessibilityLabelledBy
Android
对另一个元素的引用 nativeID 用于构建复杂的表单。accessibilityLabelledBy
的值应与相关元素的 nativeID
匹配。
<View>
<Text nativeID="formLabel">Label for Input Field</Text>
<TextInput
accessibilityLabel="input"
accessibilityLabelledBy="formLabel"
/>
</View>
在上面的示例中,当聚焦在 TextInput 上时,屏幕阅读器会宣布“输入,输入字段的标签的编辑框”。
accessibilityHint
辅助功能提示可用于在操作结果不清楚时向用户提供其他上下文信息。
在您的 View、Text 或 Touchable 上为 accessibilityHint
属性提供自定义字符串。
<TouchableOpacity
accessible={true}
accessibilityLabel="Go back"
accessibilityHint="Navigates to the previous screen"
onPress={onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Back</Text>
</View>
</TouchableOpacity>
在上面的示例中,如果用户在设备的 VoiceOver 设置中启用了提示,则 VoiceOver 会在标签后读取提示。有关 accessibilityHint
指南的更多信息,请参阅 iOS 开发者文档
在上面的示例中,TalkBack 会在标签后读取提示。目前,Android 上无法关闭提示。
accessibilityLanguage
iOS
通过使用 accessibilityLanguage
属性,屏幕阅读器将了解在读取元素的**标签**、**值**和**提示**时使用哪种语言。提供的字符串值必须遵循 BCP 47 规范。
<View
accessible={true}
accessibilityLabel="Pizza"
accessibilityLanguage="it-IT">
<Text>🍕</Text>
</View>
accessibilityIgnoresInvertColors
iOS
反转屏幕颜色是 iOS 和 iPadOS 中一项可供色盲、低视力或视力障碍人士使用的辅助功能。如果有一个视图您不希望在启用此设置时反转(可能是照片),请将此属性设置为 true
。
accessibilityLiveRegion
Android
当组件动态更改时,我们希望 TalkBack 提醒最终用户。这可以通过 accessibilityLiveRegion
属性实现。它可以设置为 none
、polite
和 assertive
- none 辅助功能服务不应宣布对该视图的更改。
- polite 辅助功能服务应宣布对该视图的更改。
- assertive 辅助功能服务应中断正在进行的语音,立即宣布对该视图的更改。
<TouchableWithoutFeedback onPress={addOne}>
<View style={styles.embedded}>
<Text>Click me</Text>
</View>
</TouchableWithoutFeedback>
<Text accessibilityLiveRegion="polite">
Clicked {count} times
</Text>
在上面的示例方法 addOne
中更改了状态变量 count
。当触发 TouchableWithoutFeedback 时,由于其 accessibilityLiveRegion="polite"
属性,TalkBack 会读取 Text 视图中的文本。
accessibilityRole
accessibilityRole
将组件的目的传达给辅助技术用户。
accessibilityRole
可以是以下之一:
- adjustable 用于元素可以“调整”的情况(例如,滑块)。
- alert 用于元素包含需要呈现给用户的重要的文本。
- button 用于元素应被视为按钮的情况。
- checkbox 用于元素表示复选框,可以选中、取消选中或具有混合选中状态。
- combobox 用于元素表示组合框,允许用户从多个选项中进行选择。
- header 用于元素充当内容部分的标题(例如,导航栏的标题)。
- image 用于元素应被视为图像的情况。可以与按钮或链接组合使用。
- imagebutton 用于元素应被视为按钮并且也是图像的情况。
- keyboardkey 用于元素充当键盘键的情况。
- link 用于元素应被视为链接的情况。
- menu 用于组件是选项菜单的情况。
- menubar 用于组件是多个菜单的容器的情况。
- menuitem 用于表示菜单中的一个项目。
- none 用于元素没有角色的情况。
- progressbar 用于表示指示任务进度的组件。
- radio 用于表示单选按钮。
- radiogroup 用于表示一组单选按钮。
- scrollbar 用于表示滚动条。
- search 用于文本字段元素也应被视为搜索字段的情况。
- spinbutton 用于表示打开选项列表的按钮。
- summary 用于元素可用于在应用首次启动时提供应用当前状况的快速摘要的情况。
- switch 用于表示可以打开和关闭的开关。
- tab 用于表示选项卡。
- tablist 用于表示选项卡列表。
- text 用于元素应被视为不可更改的静态文本的情况。
- timer 用于表示计时器。
- togglebutton 用于表示切换按钮。应与 accessibilityState checked 一起使用以指示按钮是否已切换打开或关闭。
- toolbar 用于表示工具栏(操作按钮或组件的容器)。
- grid 用于 ScrollView、VirtualizedList、FlatList 或 SectionList 以表示网格。将网格进出公告添加到 Android 的 GridView。
accessibilityState
向辅助技术用户描述组件的当前状态。
accessibilityState
是一个对象。它包含以下字段:
名称 | 描述 | 类型 | 必填 |
---|---|---|---|
disabled | 指示元素是否已禁用。 | 布尔值 | 否 |
selected | 指示可选择元素当前是否已选中。 | 布尔值 | 否 |
checked | 指示可选中元素的状态。此字段可以采用布尔值或“mixed”字符串来表示混合复选框。 | 布尔值或“mixed” | 否 |
busy | 指示元素当前是否繁忙。 | 布尔值 | 否 |
expanded | 指示可展开元素当前是展开还是折叠。 | 布尔值 | 否 |
要使用,请将 accessibilityState
设置为具有特定定义的对象。
accessibilityValue
表示组件的当前值。它可以是组件值的文本描述,或者对于基于范围的组件(如滑块和进度条),它包含范围信息(最小值、当前值和最大值)。
accessibilityValue
是一个对象。它包含以下字段:
名称 | 描述 | 类型 | 必填 |
---|---|---|---|
min | 此组件范围的最小值。 | 整数 | 如果设置了 now ,则为必填。 |
max | 此组件范围的最大值。 | 整数 | 如果设置了 now ,则为必填。 |
now | 此组件范围的当前值。 | 整数 | 否 |
text | 此组件值的文本描述。如果设置,将覆盖 min 、now 和 max 。 | 字符串 | 否 |
accessibilityViewIsModal
iOS
一个布尔值,指示 VoiceOver 是否应忽略接收器同级视图内的元素。
例如,在一个包含同级视图 A
和 B
的窗口中,在视图 B
上将 accessibilityViewIsModal
设置为 true
会导致 VoiceOver 忽略视图 A
中的元素。另一方面,如果视图 B
包含子视图 C
并且您在视图 C
上将 accessibilityViewIsModal
设置为 true
,则 VoiceOver 不会忽略视图 A
中的元素。
accessibilityElementsHidden
iOS
一个布尔值,指示此辅助功能元素中包含的辅助功能元素是否隐藏。
例如,在一个包含同级视图 A
和 B
的窗口中,在视图 B
上将 accessibilityElementsHidden
设置为 true
会导致 VoiceOver 忽略视图 B
中的元素。这类似于 Android 属性 importantForAccessibility="no-hide-descendants"
。
aria-valuemax
表示基于范围的组件(如滑块和进度条)的最大值。
aria-valuemin
表示基于范围的组件(如滑块和进度条)的最小值。
aria-valuenow
表示基于范围的组件(如滑块和进度条)的当前值。
aria-valuetext
表示组件的文本描述。
aria-busy
指示元素正在被修改,辅助技术可能需要等到更改完成之后再向用户通知更新。
类型 | 默认值 |
---|---|
布尔值 | false |
aria-checked
指示可选中元素的状态。此字段可以采用布尔值或“mixed”字符串来表示混合复选框。
类型 | 默认值 |
---|---|
布尔值,'mixed' | false |
aria-disabled
指示元素可见但已禁用,因此无法编辑或操作。
类型 | 默认值 |
---|---|
布尔值 | false |
aria-expanded
指示可展开元素当前是展开还是折叠。
类型 | 默认值 |
---|---|
布尔值 | false |
aria-hidden
指示此辅助功能元素包含的辅助功能元素是否隐藏。
例如,在一个包含同级视图A
和B
的窗口中,将视图B
上的aria-hidden
设置为true
会导致VoiceOver忽略视图B
中的元素。
类型 | 默认值 |
---|---|
布尔值 | false |
aria-label
定义一个字符串值,用于标记交互式元素。
类型 |
---|
字符串 |
aria-labelledby
Android
标识标记其应用到的元素的元素。aria-labelledby
的值应与相关元素的nativeID
匹配
<View>
<Text nativeID="formLabel">Label for Input Field</Text>
<TextInput aria-label="input" aria-labelledby="formLabel" />
</View>
类型 |
---|
字符串 |
aria-live
Android
指示元素将被更新,并描述用户代理、辅助技术和用户可以从动态区域获得的更新类型。
- off 辅助功能服务不应宣布此视图的更改。
- polite 辅助功能服务应宣布对该视图的更改。
- assertive 辅助功能服务应中断正在进行的语音,立即宣布对该视图的更改。
类型 | 默认值 |
---|---|
枚举('assertive' , 'off' , 'polite' ) | 'off' |
aria-modal
iOS
布尔值,指示VoiceOver是否应忽略接收器同级视图中的元素。
类型 | 默认值 |
---|---|
布尔值 | false |
aria-selected
指示可选择元素当前是否已选中。
类型 |
---|
布尔值 |
importantForAccessibility
Android
如果两个具有相同父级的重叠UI组件,默认的辅助功能焦点可能会出现不可预测的行为。importantForAccessibility
属性将通过控制视图是否触发辅助功能事件以及是否将其报告给辅助功能服务来解决此问题。它可以设置为auto
、yes
、no
和no-hide-descendants
(最后一个值将强制辅助功能服务忽略组件及其所有子级)。
<View style={styles.container}>
<View
style={[styles.layout, {backgroundColor: 'green'}]}
importantForAccessibility="yes">
<Text>First layout</Text>
</View>
<View
style={[styles.layout, {backgroundColor: 'yellow'}]}
importantForAccessibility="no-hide-descendants">
<Text>Second layout</Text>
</View>
</View>
在上面的示例中,yellow
布局及其所有子级对TalkBack和所有其他辅助功能服务完全不可见。因此,我们可以使用具有相同父级的重叠视图,而不会使TalkBack感到困惑。
onAccessibilityEscape
iOS
将此属性分配给一个自定义函数,当有人执行“转义”手势时,该函数将被调用,该手势是一个双指Z形手势。转义函数应在用户界面中分层向上移动。这可能意味着在导航层次结构中向上或向后移动或关闭模态用户界面。如果选定的元素没有onAccessibilityEscape
函数,则系统将尝试向上遍历视图层次结构,直到找到一个具有该函数的视图或发出提示,表明它无法找到一个。
onAccessibilityTap
使用此属性将自定义函数分配给在有人通过双击选定的可访问元素来激活它时调用的函数。
onMagicTap
iOS
将此属性分配给一个自定义函数,当有人执行“魔法点击”手势时,该函数将被调用,该手势是双指双击。魔法点击函数应执行用户可以在组件上执行的最相关操作。在iPhone上的电话应用程序中,魔法点击会接听电话或结束当前电话。如果选定的元素没有onMagicTap
函数,则系统将向上遍历视图层次结构,直到找到一个具有该函数的视图。
role
role
传达组件的目的,并且优先于accessibilityRole
属性。
role
可以是以下之一
- alert 用于元素包含需要呈现给用户的重要的文本。
- button 用于元素应被视为按钮的情况。
- checkbox 用于元素表示复选框,可以选中、取消选中或具有混合选中状态。
- combobox 用于元素表示组合框,允许用户从多个选项中进行选择。
- grid 与ScrollView、VirtualizedList、FlatList或SectionList一起使用以表示网格。向Android GridView添加网格进/出公告。
- heading 当元素充当内容部分的标题时使用(例如,导航栏的标题)。
- img 当元素应被视为图像时使用。例如,可以与按钮或链接组合使用。
- link 用于元素应被视为链接的情况。
- list 用于识别项目列表。
- menu 用于组件是选项菜单的情况。
- menubar 用于组件是多个菜单的容器的情况。
- menuitem 用于表示菜单中的一个项目。
- none 用于元素没有角色的情况。
- presentation 当元素没有角色时使用。
- progressbar 用于表示指示任务进度的组件。
- radio 用于表示单选按钮。
- radiogroup 用于表示一组单选按钮。
- scrollbar 用于表示滚动条。
- searchbox 当文本字段元素也应被视为搜索字段时使用。
- slider 当元素可以“调整”时使用(例如,滑块)。
- spinbutton 用于表示打开选项列表的按钮。
- summary 用于元素可用于在应用首次启动时提供应用当前状况的快速摘要的情况。
- switch 用于表示可以打开和关闭的开关。
- tab 用于表示选项卡。
- tablist 用于表示选项卡列表。
- timer 用于表示计时器。
- toolbar 用于表示工具栏(操作按钮或组件的容器)。
辅助功能操作
辅助功能操作允许辅助技术以编程方式调用组件的操作。为了支持辅助功能操作,组件必须执行两件事
- 通过
accessibilityActions
属性定义其支持的操作列表。 - 实现一个
onAccessibilityAction
函数来处理操作请求。
accessibilityActions
属性应包含操作对象的列表。每个操作对象应包含以下字段
名称 | 类型 | 必填 |
---|---|---|
name | 字符串 | 是 |
label | 字符串 | 否 |
操作要么表示标准操作,例如单击按钮或调整滑块,要么表示特定于给定组件的自定义操作,例如删除电子邮件消息。name
字段对于标准操作和自定义操作都是必需的,但label
对于标准操作是可选的。
在添加对标准操作的支持时,name
必须是以下之一
'magicTap'
- 仅限iOS - 当VoiceOver焦点位于组件上或组件内部时,用户用两个手指双击。'escape'
- 仅限iOS - 当VoiceOver焦点位于组件上或组件内部时,用户执行了双指擦除手势(左、右、左)。'activate'
- 激活组件。这应该在有或没有辅助技术的情况下执行相同的操作。当屏幕阅读器用户双击组件时会触发。'increment'
- 增加可调整组件的值。在iOS上,当组件具有'adjustable'
的角色并且用户将焦点放在其上并向上滑动时,VoiceOver会生成此操作。在Android上,当用户将辅助功能焦点放在组件上并按下音量增大按钮时,TalkBack会生成此操作。'decrement'
- 减小可调整组件的值。在iOS上,当组件具有'adjustable'
的角色并且用户将焦点放在其上并向下滑动时,VoiceOver会生成此操作。在Android上,当用户将辅助功能焦点放在组件上并按下音量减小按钮时,TalkBack会生成此操作。'longpress'
- 仅限Android - 当用户将辅助功能焦点放在组件上,然后双击并按住屏幕上一根手指时,会生成此操作。这应该在有或没有辅助技术的情况下执行相同的操作。
对于标准操作,label
字段是可选的,并且通常不被辅助技术使用。对于自定义操作,它是一个本地化的字符串,包含要呈现给用户的操作描述。
为了处理操作请求,组件必须实现一个onAccessibilityAction
函数。此函数的唯一参数是一个包含要执行的操作名称的事件。来自RNTester的以下示例显示了如何创建一个定义和处理多个自定义操作的组件。
<View
accessible={true}
accessibilityActions={[
{name: 'cut', label: 'cut'},
{name: 'copy', label: 'copy'},
{name: 'paste', label: 'paste'},
]}
onAccessibilityAction={event => {
switch (event.nativeEvent.actionName) {
case 'cut':
Alert.alert('Alert', 'cut action success');
break;
case 'copy':
Alert.alert('Alert', 'copy action success');
break;
case 'paste':
Alert.alert('Alert', 'paste action success');
break;
}
}}
/>
检查屏幕阅读器是否已启用
AccessibilityInfo
API允许您确定屏幕阅读器当前是否处于活动状态。有关详细信息,请参阅AccessibilityInfo 文档。
发送辅助功能事件Android
有时在UI组件上触发辅助功能事件很有用(即,当自定义视图出现在屏幕上或将辅助功能焦点设置到视图上时)。原生UIManager模块为此目的公开了方法“sendAccessibilityEvent”。它接受两个参数:视图标记和事件类型。支持的事件类型为typeWindowStateChanged
、typeViewFocused
和typeViewClicked
。
import {Platform, UIManager, findNodeHandle} from 'react-native';
if (Platform.OS === 'android') {
UIManager.sendAccessibilityEvent(
findNodeHandle(this),
UIManager.AccessibilityEventTypes.typeViewFocused,
);
}
测试TalkBack支持Android
要启用TalkBack,请转到Android设备或模拟器上的“设置”应用程序。点击“辅助功能”,然后点击“TalkBack”。切换“使用服务”开关以启用或禁用它。
Android模拟器默认未安装TalkBack。您可以通过Google Play商店在模拟器上安装TalkBack。确保选择安装了Google Play商店的模拟器。这些可以在Android Studio中找到。
您可以使用音量键快捷方式切换TalkBack。要打开音量键快捷方式,请转到“设置”应用程序,然后转到“辅助功能”。在顶部,打开音量键快捷方式。
要使用音量键快捷方式,请同时按下两个音量键3秒钟以启动辅助功能工具。
此外,如果您愿意,可以通过命令行使用以下命令切换TalkBack
# disable
adb shell settings put secure enabled_accessibility_services com.android.talkback/com.google.android.marvin.talkback.TalkBackService
# enable
adb shell settings put secure enabled_accessibility_services com.google.android.marvin.talkback/com.google.android.marvin.talkback.TalkBackService
测试VoiceOver支持iOS
要启用iOS或iPadOS设备上的VoiceOver,请转到“设置”应用程序,点击“通用”,然后点击“辅助功能”。在那里,您会发现许多可供人们使用的工具,包括VoiceOver,以使他们的设备更易于使用。要启用VoiceOver,请点击“视觉”下的“VoiceOver”,然后切换顶部出现的开关。
在“辅助功能”设置的最底部,有一个“辅助功能快捷方式”。您可以通过三次点击Home按钮来使用此快捷方式切换VoiceOver。
模拟器中无法使用VoiceOver,但您可以使用Xcode中的Accessibility Inspector通过应用程序使用macOS VoiceOver。请注意,最好使用设备进行测试,因为macOS的VoiceOver可能会导致不同的体验。