2. contentDescription 基础:设置文本描述、对 TalkBack 的影响、适用于静态文本
原理
contentDescription 是 Android 无障碍架构中最基础的语义属性。当 Composable 组件没有可直接朗读的文本(如纯图标按钮、自定义图形组件)或文本需要额外语义解释时,此属性为 AccessibilityManager 提供一段人类可读的字符串。TalkBack 等屏幕阅读器会读取该内容,而不是依赖无法识别的图形或未标注的文本。
适用对象:静态文本、图标按钮、图片、装饰性元素(此时应设为 null 以避免干扰)。对于动态内容(如倒计时数字、实时状态变化),后续章节将讲解 liveRegion 与 stateDescription。
核心原则:contentDescription 只提供一次性的、不随交互变化的静态标签。其值在组件生命周期内不自动更新,若手动更新需通过
semantics { contentDescription = newValue } 重新设置。
实现流程
- 确定组件是否需要阅读器干预(无可见文本或文本语义不足)。
- 在 Composable 内部使用
.semantics { contentDescription = "描述文字" }修饰符。 - 对于纯文本组件(
Text),Compose 默认将文本作为 contentDescription 使用,无需手动设置;但若希望覆盖默认行为,可显式指定。 - 测试:启用 TalkBack 或 Accessibility Scanner 验证朗读内容。
代码 / 配置 / API
// 1. 为图标按钮设置 contentDescription
Icon(
imageVector = Icons.Default.Info,
contentDescription = "信息" // 必填参数
)
// 2. 使用 semantics 修饰为自定义组件添加
Box(
modifier = Modifier
.size(48.dp)
.background(Color.Red)
.semantics {
contentDescription = "红色方块,表示错误状态"
}
)
// 3. 静态文本组件(Text)的默认行为
Text(text = "Hello") // TalkBack 默认朗读 "Hello"
// 若要覆盖:
Text(
text = "Hello",
modifier = Modifier.semantics { contentDescription = "问候语" }
)
调试
- 工具:Android Studio Layout Inspector → Accessibility Tree 查看每个节点的 contentDescription;或使用 Accessibility Scanner 应用扫描并提示缺失描述。
- TalkBack 手势:单指右滑浏览焦点,触摸屏幕获取焦点后双击激活。
- 确认静态组件在屏幕旋转或配置变更后 contentDescription 不丢失(Compose 重组时语义属性自动恢复)。
部署注意事项
- 不要对装饰性组件重复设置无意义的描述(如“装饰线”),应设为
null或用clearAndSetSemantics {}清除。 - 多语言环境:contentDescription 应随
stringResource变化,使用stringResource(id = R.string.desc_info)替代硬编码字符串。 - 避免 contentDescription 与组件已有文本冗余,阅读器会叠加朗读造成混乱。
常见错误
| 错误 | 后果 | 修复 |
|---|---|---|
| 对纯文本组件重复设置与文本相同的 contentDescription | TalkBack 朗读两次 | 移除显式设置,依赖默认行为 |
| 忘记设置 contentDescription 导致“未加标签”警告 | Audit 阶段严重警告,部分用户无法理解组件 | 添加语义描述 |
| 将动态数据通过 contentDescription 更新,不配合 liveRegion | TalkBack 不会自动播报变化 | 改用 liveRegion = “polite” 或 “assertive” |
| 装饰性组件设置了有意义的描述 | 分散用户注意力 | 设为 null 或使用 modifier = Modifier.semantics(mergeDescendants = true) {} |
性能与稳定性优化
静态文本的 contentDescription 在组件重组时不会产生额外开销,因为语义层仅存储一个字符串引用。注意不要在 semantics 块内执行耗时计算或分配大对象,所有描述应在组合阶段就绪。若 contentDescription 值来自 derivedStateOf 或 remember,确保其稳定以避免不必要的语义更新触发 AccessibilityEvent。
稳定性陷阱:将 contentDescription 绑定到不稳定的参数(如每次重组都生成新对象的字符串拼接)会导致 AccessibilityManager 频繁注册事件,可能造成卡顿。使用
remember 缓存静态字符串。
工作流示意图
本章小结:contentDescription 是无障碍属性的基石,直接定义组件可被阅读器理解的文本。静态文本场景下,只需一次设置便可获得正确朗读;务必避免重复、冗余或遗漏,并通过 Accessibility Scanner 或 TalkBack 实际验证。