2. contentDescription 基础:设置文本描述、对 TalkBack 的影响、适用于静态文本

原理

contentDescription 是 Android 无障碍架构中最基础的语义属性。当 Composable 组件没有可直接朗读的文本(如纯图标按钮、自定义图形组件)或文本需要额外语义解释时,此属性为 AccessibilityManager 提供一段人类可读的字符串。TalkBack 等屏幕阅读器会读取该内容,而不是依赖无法识别的图形或未标注的文本。

适用对象:静态文本、图标按钮、图片、装饰性元素(此时应设为 null 以避免干扰)。对于动态内容(如倒计时数字、实时状态变化),后续章节将讲解 liveRegion 与 stateDescription。

核心原则:contentDescription 只提供一次性的、不随交互变化的静态标签。其值在组件生命周期内不自动更新,若手动更新需通过 semantics { contentDescription = newValue } 重新设置。

实现流程

  1. 确定组件是否需要阅读器干预(无可见文本或文本语义不足)。
  2. 在 Composable 内部使用 .semantics { contentDescription = "描述文字" } 修饰符。
  3. 对于纯文本组件(Text),Compose 默认将文本作为 contentDescription 使用,无需手动设置;但若希望覆盖默认行为,可显式指定。
  4. 测试:启用 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 与组件已有文本冗余,阅读器会叠加朗读造成混乱。

常见错误

错误后果修复
对纯文本组件重复设置与文本相同的 contentDescriptionTalkBack 朗读两次移除显式设置,依赖默认行为
忘记设置 contentDescription 导致“未加标签”警告Audit 阶段严重警告,部分用户无法理解组件添加语义描述
将动态数据通过 contentDescription 更新,不配合 liveRegionTalkBack 不会自动播报变化改用 liveRegion = “polite” 或 “assertive”
装饰性组件设置了有意义的描述分散用户注意力设为 null 或使用 modifier = Modifier.semantics(mergeDescendants = true) {}

性能与稳定性优化

静态文本的 contentDescription 在组件重组时不会产生额外开销,因为语义层仅存储一个字符串引用。注意不要在 semantics 块内执行耗时计算或分配大对象,所有描述应在组合阶段就绪。若 contentDescription 值来自 derivedStateOf 或 remember,确保其稳定以避免不必要的语义更新触发 AccessibilityEvent。

稳定性陷阱:将 contentDescription 绑定到不稳定的参数(如每次重组都生成新对象的字符串拼接)会导致 AccessibilityManager 频繁注册事件,可能造成卡顿。使用 remember 缓存静态字符串。

工作流示意图

contentDescription 无障碍工作流(静态文本) Composable 组件 contentDescription “信息” Accessibility 无障碍框架 TalkBack 合成语音 → 用户 用户感知 听到“信息” 适用于静态文本(图标、固定标签、纯图形)。动态内容需结合 liveRegion 或 stateDescription。
本章小结:contentDescription 是无障碍属性的基石,直接定义组件可被阅读器理解的文本。静态文本场景下,只需一次设置便可获得正确朗读;务必避免重复、冗余或遗漏,并通过 Accessibility Scanner 或 TalkBack 实际验证。