鸿蒙开发多维信息整体朗读:嵌套组的重复播报怎么破
上一篇咱们讲了
accessibilityGroup把多个组件聚合成一个焦点。但实际开发中,信息往往是多维的、有层级结构的——卡片里套卡片,分组里再分组。这时候光会"聚合"还不够,还得会处理嵌套组里的重复朗读问题。这篇就聊这个更进阶的场景。
一、什么情况会出现"嵌套组"
先定义一下场景。所谓"嵌套组",就是一个已经做了聚合的语义单元里,还包含着可以独立获焦的子对象。典型例子是天气卡片:
- 外层:一张天气卡片,包含"时间 + 地点"这一组信息
- 内层:时间"12:05"是一个焦点候选,地点"北京"是另一个焦点候选
如果处理不当,用户滑动到这张卡片时,会先听到一次"时间组 12:05 北京"(外层聚合的整体朗读),再继续滑动,又听到"12:05",再滑一下,又听到"北京"——同一个信息被播报了两遍。
这就是多维信息场景的核心问题:层级结构带来的重复朗读。
二、官方给出的原则
官方文档针对这个场景的原则很明确:
应避免两个可获焦对象的功能或朗读内容产生重复。
翻译过来就是:如果某个信息的完整描述,已经在一个父控件的整体朗读里覆盖了,那就不应该再让子控件独立获焦、重复播报。对同一个信息结构的完整描述,应该统一标注在父控件上,子控件不再单独获焦。
这个原则和上一篇"聚合边界 = 语义边界"一脉相承,只是它特别针对有嵌套层级的情况,防止你聚了一层却漏了另一层。
三、错误写法:父控件和子控件都在读
看一个典型的错误示范。下面这个 Row 既设了父级的无障碍文本,子控件又各自保留了独立朗读能力:
Row(){
Text('12:05') // 时间,可独立聚焦
.fontSize(32)
.fontColor(Color.Red)
.fontWeight(FontWeight.Bold)
Text('Beijing') // 地点,可独立聚焦
.fontSize(20)
.fontColor(Color.Green)
.fontWeight(FontWeight.Bold)
}
.accessibilityText('Time Group') // 父级也设了文本
.height(50)
这把雷全踩了:
- 父级 Row 通过
accessibilityText('Time Group')提供了一个朗读入口 - 子控件"12:05"和"Beijing"依然可以独立获焦、独立朗读
结果就是:焦点落在父级时读"Time Group 12:05 Beijing",继续滑到子控件又读"12:05"、再读"Beijing"。官方注释直接点明这是"不正确的"——信息重复了两次。
四、正确写法:父级统一描述,子级禁止单独获焦
正确做法是把这个信息结构在父级完整标注,然后让子控件不再单独获焦:
Row(){
Text('07:05') // 不再独立聚焦
.fontSize(32)
.fontColor(Color.Red)
.fontWeight(FontWeight.Bold)
Text('Moscow') // 不再独立聚焦
.fontSize(20)
.fontColor(Color.Green)
.fontWeight(FontWeight.Bold)
}
.height(50)
.accessibilityGroup(true) // 整组一个焦点,读 "07:05 Moscow"
注意,这里用的是 accessibilityGroup(true),而不是 accessibilityText。区别很关键:
accessibilityGroup(true)会阻止子控件独立获焦,同时把子控件的内容整合进整体朗读,读出来是"07:05 Moscow"- 光设
accessibilityText不会阻止子控件获焦,反而会和子控件的朗读重复
这就是上一篇错误示范里注解说"子组件无法聚焦、无法朗读"的原因——accessibilityGroup 才是真正"收口"的那个属性,accessibilityText 只是"附加一段朗读内容"。
五、多维信息处理的三个层次
把多维信息的处理策略分层,会清晰很多:
层次一:扁平信息聚合
最简单的场景,多个平级组件描述同一个对象。直接用 accessibilityGroup(true) 把整组打包,一次读完整信息。上一篇天气卡片的例子就属于这层。
层次二:嵌套信息的收口
有层级结构时,父级做统一标注,子级禁止独立获焦。确保"每一个语义单元只有一个朗读入口",消灭重复播报。
层次三:可操作元素的保留
如果嵌套结构里有些元素是用户需要独立操作的(比如卡片里的收藏按钮),那就不能简单地把全部子控件都吞进父组。这种情况下,可操作元素要跳出父组聚合范围,保持独立焦点,只把纯展示信息聚合。
六、一个实操建议:先画语义树
处理多维信息时,一个很有效的方法是先在纸面上画"语义树",把界面信息拆成层级:
天气卡片(一个语义单元)
├── 时间:12:05
└── 地点:北京
然后自问一个问题:视障用户理解这条信息,需要几步朗读?
答案如果是一个焦点、一次朗读就能说清楚,那就应该聚合到根节点,子节点全部收口。如果需要分步骤(比如先选城市、再看天气、再操作某个按钮),才保留多个焦点。
这个"一步还是多步"的判断,比任何技术细节都更本质。
七、总结一下下
多维信息整体朗读,本质是解决"重复"——重复的焦点、重复的朗读、重复的操作。核心原则一句话:同一个信息结构,只保留一个朗读入口。
实操上就三条:
- 扁平信息用
accessibilityGroup(true)聚合 - 嵌套信息父级标注、子级收口,用
accessibilityGroup而非accessibilityText - 需要独立操作的元素保留独立焦点,不参与聚合
下一篇转向另一个维度——焦点已经聚合好了,但焦点位置可能会因为控件消失、页面跳转而"跑丢",这时该怎么主动管理焦点。
更多推荐

所有评论(0)