在日常生活中,我们经常会在公共设施说明上,看到一个词“无障碍设施”,对应的英文单词:Accessibility——常见多种译法:可访问性、无障碍性、辅助功能等等,其中文意思都不太能准确表达其功能的本质——即为残障人士提供便利。这类设施主要是为了照顾有行动障碍的人。除了行动障碍,还有视觉障碍,心理障碍,语言障碍等等。
世界卫生组织 2018 年公布的统计数据 显示,全球有超过 10 亿人患有某种形式的残疾,约占到世界人口的 15%,其中 1.1 亿至 1.9 亿成年人有很严重的功能性障碍,包括去年世卫 估计 的全球 4.66 亿耳聋及听障人士,预计到 2050 年,世界上将有 9 亿多人(或者说十分之一的人)出现残疾性听力损失;在国内,残联会 2019 年的统计公报显示,全国残疾人人口基础数据库入库持证残疾人 3681.7 万人。[1]
随着到家业务的发展,用户群体也越来越多样性,其中就出现了上述群体中的一类,视觉障碍群体,他们出行不便,而我们的服务,可以让他们避免出行即可获取到日常生活物资。服务本身得到了认可,但是在我们的RN应用未做无障碍适配的之前,对于这类用户来说,使用门槛较高,应用过程遇到诸多不便。
举个例子:假设A用户是一个患有视觉障碍,不能正常看到手机屏幕上的内容,但是A现在需要点中应用内的超市入口,这听起来有点怪怪的,和前面的假设条件完全冲突,既然看不到,怎么能知道超市入口在什么位置呢?
手机系统提供的“无障碍功能”,他能在A用户用手在屏幕上滑动的时候,读出选中模块设定的文本描述,从而让用户用听觉代替视觉去使用我们的手机应用。
为了解决上述类似问题,我们从2020年初开始对京东到家RN平台进行无障碍全面适配。
在RN开始适配前,到家iOS app已经先行一步,为了了解无障碍适配需要做哪些,使用哪种方案比较合适。我们和iOS团队进行了详细的沟通,结果发现,iOS可以将视图放进数组来告诉无障碍系统哪些是无障碍元素。考虑目前RN现状,这一点JSX暂时无法做到。通过技术调研,目前JSX需要在标签上添加无障碍功能相关属性,来让无障碍系统识别,部分语音反馈动作需要原生提供api支撑,这个在后面规范制定的章节会给出方案。
通过文档学习和试验,我们得到RN无障碍适配要解决的问题,共4个:
1. 层级穿透问题
如果页面上出现层级叠加时,无障碍在读取弹层内容时,会读取下层容器上的元素文本信息,干扰到障碍用户无法得到准确的引导信息以及无法正确的选中上层元素,从而导致下单流程受到阻碍。
2. 组件可读性及正确的信息朗读顺序问题(以下简称组件可读性)
① 有些按钮是图片按钮,无障碍并不能给出应有的点击引导信息
② 部分文本的信息朗读顺序不正确
3. 操作反馈问题
例如:用户点击关注门店按钮,系统会提示Toast,告知用户已关注,但是视觉障碍用户需要用听觉去感触,所以需要适配成语音提示。
4. UI元素交互问题
① Banner自动切换后,未自动聚焦到切换后当前显示的Slider上
② 弹层弹起时,未能聚焦,且未提示当前弹层的功能
整理并输出无障碍从调研到适配工作的流程图,如下:
到家RN做无障碍适配的目标是让障碍用户能使用我们的RN应用正常的购买商品。
我们要做以下工作:
梳理适配主流程
首先是通过对主流程的梳理,可以制定一个长期可遵循的最终目标规划,且有个清晰的目的,使得做这件事情方向更明确。
我们从实际的业务需求入手,梳理出一个明确的用户下单的主流程,对用户正常进店,选品,加车,下单,结算到订单的主要节点进行针对性的适配,最终达到对于主要节点的全面的无障碍覆盖,确保障碍用户能够完成完整下单流程。
如图3-1。
图3-1 主流程图
目标规划
针对需要解决的问题,团队讨论并制定出解决优先级,从高到低:
结合优先级,输出目标整体的时间规划:
图3-2 目标整体时间规划实现方案
针对各个目标,我们梳理出针对上述问题的技术解决方案。
1. 解决层级穿透问题
理论上层级穿透应该有焦点和索引进行配合解决该问题,但是根据现状,功能模块和层级数量较多,我们采用折中方案,让系统忽略下层不需要识别的元素来解决该问题。
RN针对安卓和iOS分别提供了设置方式:
① Android
属性名称:importantForAccessibility
值类型:string
值可选值:auto|yes|no|no-hide-descendants
示例代码:
当设置importantForAccessibility="no-hide-descendants"时,Android无障碍服务将忽略其及其子元素。
② iOS
属性名称:accessibilityElementsHidden
值类型:boolean
示例代码:
当设置accessibilityElementsHidden=true时,表示,iOS无障碍服务将忽略其及其子元素。
注: 同时设置上述两个属性,兼容两个系统。
2. 解决组件可读性及正确的信息朗读顺序问题
该问题主要涉及到3个属性,分别是:
① accessible —— 设置为true时表示当前视图是一个“无障碍元素”(accessibility element)。无障碍元素会将其所有子组件视为一整个可以选中的组件。并将其下文本元素都依序读出来。
② accessibilityLabel —— 当一个视图启用无障碍属性后,再加上 accessibilityLabel(无障碍标签),这样可以让使用无障碍功能的用户清楚地知道自己选中了什么。无障碍功能会读出选中元素的无障碍标签。
③ accessibilityHint —— 无障碍提示,用于帮助用户理解当前操作的说明
示例代码:
<touchableopacity< code="">
accessible={true}
accessibilityLabel="门店名称"
accessibilityHint="点击前往该门店"
onPress={this._onPress}>
3. 解决操作反馈问题
当用户点击某个按钮操作之后,需要给用户反馈语音结果。
这里推荐大家使用react-native-tts库。
示例代码:
Tts.getInitStatus().then(() => {
Tts.speak('Hello, 京东到家!');
});
4. 解决UI元素交互问题
当元素聚焦时,我们使用无障碍API改变元素焦点。
示例代码:
const reactTag = findNodeHandle(myElement.current);
if (reactTag) {
AccessibilityInfo.setAccessibilityFocus(reactTag);
}
注:被选中的元素,如果需要自动被无障碍朗读,需要增加accessible={true}属性。
针对各类型问题给出了明确的解决方案及示例。除了这些场景问题外,还有一个很重要的api在适配无障碍时,经常使用到:判断当前手机系统是否已开启无障碍服务。
开启代码如下:
import { AccessibilityInfo } from 'react-native';
......
AccessibilityInfo.fetch().done((enabled) => {
this.setState({
AccessibilityEnabled: enabled
});
});
AccessibilityInfo.addEventListener('change',this.handleAccessibilityChange);
......
handleAccessibilityChange = (isEnabled) => {
this.setState({
AccessibilityEnabled: isEnabled
});
}
// 记得在组件销毁前,remove事件
AccessibilityInfo.removeEventListener(
'change',
this.handleAccessibilityChange
);
4 适配问题&规范的制定
通过无障碍适配在京东到家RN中的实践,我们发现:
问题一:在适配过程中,团队在适配无障碍时,总会不知从何入手进行适配的开发工作。为此,制定了一套无障碍适配规范,以及开发流程图。
我们规定以下6种类型元素需要进行无障碍适配,并给出适配细则:
① 基础元素适配
包含按钮、文本、图片、标签。需要给出明确的语义描述内容,使用accessibilityLabel属性进行适配。
按钮需要增加明确的标识属性accessibilityRole="button",并需要给出点击后的动作提示,使用属性accessibilityHint进行适配。
② 组合元素适配
当多个元素可被用户整体选中,进行统一动作的元素被视为组合元素。例如:入口球。此类元素需要在最外层容器View上增加属性accessible={true},标识多个元素作为整体被选中。
③ 弹层元素适配
弹层包含Alert和Popup两种。此类型元素弹出时,将覆盖下层页面。为了让无障碍知晓弹层弹出时,忽略对下层页面元素的识别。需要同时增加两个属性importantForAccessibility和accessibilityElementsHidden,分别对应Android和iOS两个平台的适配开发。
④ 页面级适配
当打开多级页面时,为避免无障碍识别到下层被遮盖的页面元素,需要忽略对下层页面的识别。需要同时增加两个属性importantForAccessibility和accessibilityElementsHidden,分别对应Android和iOS两个平台的适配开发。
⑤ 元素状态适配
当元素有禁用和可用两种状态时,需要告知无障碍当前元素状态情况,需使用属性accessibilityStates进行适配。
⑥ 交互元素
分为两类:一、自动切换类的Banner;二、元素操作有提示行为。
针对一,Banner聚焦被选中时,需要在Banner切换Slide后,自动改变焦点,保证无障碍及时识别当前显示的Slide。使用Api:AccessibilityInfo.setAccessibilityFocus。
针对二,当元素经过用户触发某种行为后,给予用户反馈,需要使用Api,Tts.speak及时对用户进行语音反馈。相关京东React文档地址:https://njst.360buyimg.com/jdreact/introduction/apis/JDReactTextToSpeech.html
上述规范中使用到的属性用法请见文档:https://reactnative.cn/docs/next/accessibility
开发流程图:
问题二:现有的开发流程中未有涉及到无障碍适配的环节。但是在版本迭代过程中,很多适配的无障碍功能会被修改到,移除,新增需求等操作,都需要重新对无障碍进行适配。
因此我们在代码Review阶段,增加对无障碍适配规范的审查环节。这样不仅可以增加大家对无障碍适配的认知,也可以避免需求迭代对无障碍适配功能带来的不必要的影响。
针对这个问题,接下来我们也会继续探索自动化方案,在代码编译阶段,通过规则检查类型元素是否已经按照规范进行适配,并对相应的开发人员给出适配规范提示。从而减小人工审核的成本。
5 总结
无障碍适配在京东到家RN中的实践,表明ReactNative项目进行无障碍适配是可行的。在实践过程中,我们为团队制定了适配规范,并将规范执行落地,降低适配开发的门槛。同时,为解决需求迭代对无障碍适配的影响,我们将适配审核放到Review阶段,保证适配功能跟随需求持续迭代,将影响降到最低。未来,我们将继续探索自动化审核方案,持续为降低人力成本做出努力。
本次适配工作,我们已经完成对目标规划的流程适配工作。保证了障碍用户无忧购买商品。
无障碍适配的实践也让我们体会到,科技属于每一个人。这里要感谢各大手机厂商在默默的从底层支撑着信息无障碍的的发展,让科技进步带来的便利实际帮助到各个群体。
作者简介:章文顺,RN无障碍适配工作负责人,到家前端团队高级前端工程师。
Tracy:绿色不是成本!
6409 阅读靠供应链暴赚、大建冷链物流,年营收77亿的奶茶品牌冲刺IPO
2799 阅读极智嘉冲刺港交所,为全球最大的仓储履约AMR解决方案提供商(附招股书下载)
2726 阅读跃点物流科技获350万美元A+轮融资
2624 阅读快递停摆风波再起,又是共配惹的祸?
1632 阅读顺丰、鲜生活、京东物流、万纬物流、普冷、菜鸟…谁家冷链能在2025实现新突破?
1542 阅读赢在供应链:外包战略的系统性思考
1506 阅读京东物流发布全球织网计划2.0路线图:全面构建海外仓配“2-3日达”时效圈
1350 阅读像吃大象一样优化物流成本:企业降本增效的系统方法
1199 阅读大胆预测:2025供应链趋势抢先看
1183 阅读