Android辅助功能

让 App 能被视障用户使用——contentDescription、焦点顺序、TalkBack 测试和可访问性最佳实践。

学习目标

  • 能沿“Android辅助功能”的用户事件解释Android组件、状态所有者、线程与销毁边界。
  • 能围绕“让 App 能被视障用户使用——contentDescription、焦点顺序、TalkBack 测试和可访问性最佳实践。”改出一个可运行结果,并用前后状态而非组件数量验收。
  • 能在旋转、进程重建、拒权、离线或无效输入中选择适用反例,定位首个状态分叉。
  • 能用双视口、大字体、焦点顺序、状态语义和对比度截图独立重放结论,并标明第四版机制与现代targetSdk政策的边界。

你的 App 可能有一批"看不见"的用户

全球数亿人有视力障碍,他们通过 使用手机——手指滑动屏幕,TalkBack 朗读手指碰到的元素。如果你的 App 不给 ImageView 加 contentDescription,TalkBack 用户听到的就是"未加标签的按钮"——他们完全不知道这按钮是干什么的。

无障碍(Accessibility)不是可选的"附加功能"——它是让产品能被所有人使用的基础要求。

TalkBack 看到的不是你界面上的像素,而是一棵无障碍语义树:每个可聚焦控件是一个节点,TalkBack 朗读它的 contentDescription 或文本,并按从上到下、从左到右的顺序遍历焦点。下图把同一个界面和它对应的语义树并排放在一起,看清"用户看到的"和"TalkBack 听到的"差在哪。

无障碍语义树:界面控件 → TalkBack 朗读什么、按什么顺序读每个可聚焦控件 = 一个语义节点;TalkBack 从上到下、从左到右遍历焦点,触摸探索 + 双击激活界面(用户看到的)无障碍语义树(TalkBack 听到的)焦点遍历◉ 拍照ImageButton1朗读:拍照clickable=true → 双击激活犯罪现场照片TextView2朗读:犯罪现场照片clickable=false → 仅朗读▬▬▬▬▬ImageView(装饰分割图)⊘ 跳过(不进焦点遍历)importantForAccessibility="no"2024-03-12 已处理列表项(可点击)3朗读:2024 年 3 月 12 日,已处理,按钮clickable=true → 双击激活记住四条:① ImageButton / ImageView 不设 contentDescription,TalkBack 只会读「未加标签的按钮」② 纯装饰图设 importantForAccessibility="no" 被跳过 ③ 焦点从上到下、从左到右遍历④ 用户用手指划过屏幕触摸探索(朗读当前控件),再双击激活它
TalkBack 看到的不是像素,而是这棵 无障碍语义树 :每个可聚焦控件是一个节点,朗读它的 contentDescription 或文本,并按从上到下、从左到右 遍历焦点 。图标类控件不设 contentDescription 就会被读成「未加标签的按钮」;纯装饰图设 importantForAccessibility="no" 让阅读器跳过。用户靠触摸探索朗读、双击激活。

基本无障碍属性

contentDescription

<!-- ❌ 差:TalkBack 读不了 -->
 
<!-- ✅ 好:TalkBack 会读"发送消息" -->

纯装饰性图片(比如背景花纹)设 android:contentDescription="@null" —— TalkBack 会跳过它。

焦点顺序

默认情况下,TalkBack 按布局文件顺序从左到右、从上到下朗读。如果布局跟视觉顺序不一致,用 nextFocusForward 等属性调整:

 

测试无障碍

Android Studio 内置 Accessibility Scanner——一键扫描当前页面,自动检测缺失的 contentDescription、对比度不足、触摸区域太小等问题。开启 TalkBack(设置→无障碍→TalkBack),实际操作一遍 App,感受视障用户的体验。

分步1 / 5

① 开启 TalkBack

进入"设置 → 无障碍 → TalkBack",打开开关。听到语音反馈即表示激活成功。注意:TalkBack 的手势逻辑与常规操作不同——单指滑动切换焦点,双击触发点击。

容易踩的坑

小结

  • contentDescription 是 TalkBack 用户"看到"你界面的唯一窗口——写有意义的描述
  • 装饰性图片设 @null 避免干扰;按钮/图标必须有描述
  • 焦点顺序确保朗读顺序符合用户预期
  • Accessibility Scanner 自动检测常见无障碍问题
  • 无障碍设计惠及所有人——高对比度字幕所有人看得更清,大触摸区域所有人点得更准

练习

问题 1:“第18章 Accessibility”覆盖哪些正式节点和项目主线?

问题 2:怎样建立本页最小可执行实验?

问题 3:为什么只在正常点击路径运行不能证明完成?

问题 4:怎样设计能推翻当前实现的反例?

问题 5:从第4版语境迁移到现代目标SDK时如何控制变量?

问题 6:本页达到独立交接标准需要什么?

名词解释

本章出现的专业名词,用大白话再讲一遍。

TalkBack

Android 内置的屏幕阅读器。视障用户通过触摸和滑动手势导航界面,TalkBack 朗读手指触碰到的元素内容。

Accessibility Scanner

Google 提供的无障碍扫描工具。分析当前界面,自动检测缺失的 contentDescription、对比度问题、触摸区域过小等无障碍缺陷。

“Android辅助功能”不使用未获授权的纸书正文;InformIT出版信息授权电子版完整目录只用于确认第四版32章、269个正式目录节点和时代语境,第四版官方勘误用于识别工具链变更。下列中文解释、图示、交互、代码与练习均为独立教学重写,平台行为再以Android Developers的一手文档复核。

为什么“Android辅助功能”必须回到可观察状态

“Android辅助功能”的学习结果不是记住类名,而是能预测“让 App 能被视障用户使用——contentDescription、焦点顺序、TalkBack 测试和可访问性最佳实践。”在一次输入、一次重建和一次失败中的不同状态,并指出哪条Android合同产生差异。

第四版机制逐项深读

18. Accessibility

在“Android辅助功能”中,“18. Accessibility”的通过条件是可比较体验,不是扫描器零告警;动态错误、超时与音频反馈仍需人工验证。

TalkBack

在“Android辅助功能”中,分析“TalkBack”按TalkBack线性焦点顺序走完整任务,检查自定义控件是否暴露可执行action与状态变化。

Making Non-Text Elements Readable by TalkBack

在“Android辅助功能”中,分析“Making Non-Text Elements Readable by TalkBack”按TalkBack线性焦点顺序走完整任务,检查自定义控件是否暴露可执行action与状态变化。

Creating a Comparable Experience

在“Android辅助功能”中,“Creating a Comparable Experience”要求可访问性树表达与视觉界面等价的名称、角色、状态和操作;contentDescription不能重复可见文本或描述装饰。

For the More Curious: Using Accessibility Scanner

在“Android辅助功能”中,“For the More Curious: Using Accessibility Scanner”的通过条件是可比较体验,不是扫描器零告警;动态错误、超时与音频反馈仍需人工验证。

Challenge: Improving the List

在“Android辅助功能”中,“Challenge: Improving the List”用于推翻“让 App 能被视障用户使用——contentDescription、焦点顺序、TalkBack 测试和可访问性最佳实践。”的顺利路径:先写预期,再引入一个边界输入、重建或平台差异,并用状态、日志与用户结果解释首个分叉。

Challenge: Providing Enough Context for Data Entry

在“Android辅助功能”中,“Challenge: Providing Enough Context for Data Entry”用于推翻“让 App 能被视障用户使用——contentDescription、焦点顺序、TalkBack 测试和可访问性最佳实践。”的顺利路径:先写预期,再引入一个边界输入、重建或平台差异,并用状态、日志与用户结果解释首个分叉。

Challenge: Announcing Events

在“Android辅助功能”中,验证“Challenge: Announcing Events”在大字体、触摸探索和无视觉条件下完成同一任务,并记录首个焦点陷阱或缺失播报。

“Android辅助功能”验收回顾

“Android辅助功能”只有在双视口、大字体、焦点顺序、状态语义和对比度截图能够从相同基线再次得到相同断言时才通过;第四版机制与现代平台政策分别记录,不用新API名称掩盖旧行为。

← 上一页:应用本地化 · 下一页:数据绑定与MVVM →

讨论

评论区加载中…