鸿蒙开发按钮与图标标注:可交互控件无障碍的必修课
在无障碍开发里,按钮和图标是两座绕不开的山。它们是用户操作的核心入口,偏偏又最容易"读不出来"——因为大量按钮根本不用文字,而是靠图标。这篇文章专注讲可交互控件的标注,尤其那几个自定义控件和虚拟按钮区域的坑。
一、为什么按钮是重灾区
按钮在任何应用的语义里都是"用户能点、能操作"的东西。屏幕朗读模式下,视障用户探索界面的基本动作,就是靠焦点在元素间移动,靠朗读判断"这是什么、能不能点、点了会怎样"。
文本按钮天然有显示文本,朗读没问题。真正麻烦的是这几类:
- 图标按钮:
Image或Image包成的可点击区域,没有任何文字 - 自定义控件:开发者用 Canvas、自定义绘制实现的可点击区域,系统根本不认识这是按钮
- 虚拟按钮区域:一个大的
Column里,某个区域点击会触发动作,但它不是标准 Button 组件
官方文档针对这个场景说得很直接:任何可点击的按钮,只要不是文本类控件,就必须给出标注信息,否则屏幕朗读用户无法完成对应功能。
这条是"必须",不是"建议"。
二、标准做法:角色 + 文本
先看一个最标准的图标按钮标注。播放/暂停按钮,前面文章提过,这里再完整过一遍每个属性的作用:
const RESOURCE_STR_PLAY: Resource = $r('sys.media.ohos_ic_public_play');
const RESOURCE_STR_PAUSE: Resource = $r('sys.media.ohos_ic_public_pause');
@Entry
@Component
export struct PlayButton {
@State isPlaying: boolean = false;
build() {
Column() {
Row() {
Image(this.isPlaying ? RESOURCE_STR_PAUSE : RESOURCE_STR_PLAY)
.width(50)
.height(50)
.accessibilityRole(AccessibilityRoleType.BUTTON)
.accessibilityText(this.isPlaying ? '暂停' : '播放')
.onClick(() => {
this.isPlaying = !this.isPlaying;
})
Text('Good_morning.mp3')
.margin({ left: 10 })
}
}
}
}
拆解一下,三个无障碍相关的点:
accessibilityRole(AccessibilityRoleType.BUTTON):声明"这是个按钮"。这个声明会带来两个效果——系统会按按钮来处理它的焦点和交互语义,朗读时自动追加"按钮"后缀accessibilityText():给朗读内容。注意这里文本跟状态绑定,播放态读"暂停"、暂停态读"播放"- 标注不含类型词:没有写"播放按钮",只写了"播放",因为后缀系统会加
三、状态型图标的文本要跟着变
上面例子里最值得强调的是 accessibilityText(this.isPlaying ? '暂停' : '播放') 这一行。
很多开发者图省事,给一个图标按钮设一个固定的无障碍文本,忽略了图标本身是会根据状态改变的。结果就是:
- 用户看到(假如能看到)图标是"暂停",但听到的是"播放"
- 或者反过来
这种"视听不一致"对无障碍用户是致命的误导。记住一条原则:图标的视觉状态变了,无障碍文本也要同步变。播放/暂停、收藏/取消收藏、静音/取消静音,全都适用。
四、自定义控件的虚拟按钮区域
这是最容易被遗漏的场景。官方文档特别提醒:用户自定义控件中的虚拟按钮区域也要标注。
什么叫"虚拟按钮区域"?就是你在一个自定义组件里,划出一块区域响应点击,但底层不是标准 Button 组件。比如:
- 一个 Canvas 画出来的播放器,进度条某个位置可点击
- 一个自定义游戏板,某个格子可以落子
- 一个自绘的日历,某个日期格可以选中
这些区域对系统来说就是"一块绘制",系统不知道它是可交互的,更不知道它是什么、点了会干嘛。如果不标注,视障用户完全感知不到这里有个操作入口。
处理这类场景的思路:
- 先把这块区域用
accessibilityRole声明成合适的角色(按钮、可选中项等) - 再用
accessibilityText描述它的功能和状态 - 如果这块区域没有独立的组件承载,要考虑给承载它的容器做标注
五、标注文本的两个禁忌(再强调一次)
按钮标注有两个高频错误,官方文档明确点出来了,这里再强调一遍,因为太常见了。
5.1 不要写控件类型
标注文本里不要出现"按钮"字样。系统会根据 accessibilityRole 自动追加类型。你写了"播放按钮",最终读出来就是"播放按钮,按钮"。
5.2 不要写操作指引
"单指双击即可打开"这种话,属于新手指引的内容。系统会根据控件类型、控件状态、用户是否开启新手引导来自动追加。硬编码进去只会造成信息重复和啰嗦。
六、图标按钮标注清单
把按钮/图标标注总结成一个 checklist,code review 时逐条过:
- 可点击控件的组件类型是否已通过
accessibilityRole声明 - 非文本按钮是否设置了
accessibilityText - 状态型图标按钮的无障碍文本是否跟随状态变化
- 标注文本没有包含控件类型词
- 标注文本没有包含操作指引
- 自定义控件中的虚拟按钮区域是否遗漏标注
七、一个额外提醒:点击区域大小
严格说这不算无障碍文本的范畴,但和按钮可用性强相关。低视力用户、老年人、手部活动受限的用户,需要更大的点击区域。图标按钮通常很小,建议扩大它的实际热区(比如给 Image 加足够的 padding,或用不可见的容器扩展点击范围),而不是让用户精确地戳那个 24×24 的图标。
八、总结一下下
按钮和图标标注的原则其实就一条:让视障用户靠听觉获得和明眼用户靠视觉一样的信息。明眼用户看到"一个播放图标",知道"这是个能点的按钮、点了会播放";视障用户就得靠"播放,按钮"这几个字补回同样的认知。
把这篇讲的角色 + 文本 + 状态同步三件事做扎实,可交互控件的无障碍基本就立住了。下一篇进入另一个高频主题——多个组件怎么组合成一个焦点,避免朗读碎片化。
更多推荐

所有评论(0)