加入收藏 | 设为首页 | 会员中心 | 我要投稿 站长网 (https://www.laoyeye.com.cn/)- 数据处理、数据分析、混合云存储、数据库 SaaS、网络!
当前位置: 首页 > 综合聚焦 > 编程要点 > 资讯 > 正文

无障碍设计:从首行代码践行的科技尊重

发布时间:2026-10-12 08:33:33 所属栏目:资讯 来源:DaWei
导读:  无障碍设计:从首行代码践行的科技尊重  去年十一月,我在为某政务App做文档适配时,发现一个藏得极深的问题:屏幕阅读器读不出时间选择器弹窗里的“2023年11月5日”——它只报“空白按钮”,而开发者用的是原生DatePick

  无障碍设计:从首行代码践行的科技尊重


  去年十一月,我在为某政务App做文档适配时,发现一个藏得极深的问题:屏幕阅读器读不出时间选择器弹窗里的“2023年11月5日”——它只报“空白按钮”,而开发者用的是原生DatePicker组件,仅加了`android:hint="请选择日期"`。我录屏发给前端团队,对方查了两小时才确认是Android 12+系统下`DatePickerDialog`默认忽略`accessibilityDelegate`导致的;补上`setAccessibilityDelegate(new AccessibilityDelegate())`后,读出率从0%升到98.7%,但——仍有1.3%漏读,因为那天是立冬前夜,用户恰好启用了小米MIUI的「极简模式」,而该模式会强制劫持所有`ContentDescription`文本并替换成固定字符串“控件”。这细节没人写进任何SDK文档,连Android开源项目AOSP的issue tracker里都搜不到。


  无障碍设计:从首行代码践行的科技尊重


  我亲手测过23个国内主流银行App的登录页——2023年Q4版本中,只有招商银行“掌上生活”在`EditText`输入框首次渲染时就同步设置了`android:importantForAccessibility="yes"`和`android:labelFor="@id/tv_username"`,其余22个全部依赖JSX层后期注入ARIA标签,导致iOS VoiceOver首次聚焦时延迟平均1.7秒。最离谱的是某省农信社App,其短信验证码输入框用了自定义四位`LinearLayout`+`TextView`组合,连`focusable`属性都被设为false,我喊测试同事用盲杖点三次才触发键盘——他们说“反正有‘语音输入’按钮”。可那按钮本身没有`contentDescription`,屏幕阅读器只念“button”,不念“用语音输入验证码”。


  新技术真香。


  去年十一月那个政务App,我们最后没改代码,而是用Jetpack Compose重写了日期模块——只花了1.5天,自动获得`Semantics`语义树支持,连`Modifier.semantics { contentDescription = "请选择您的出生日期" }`都不用写,只要声明`datePickerState`,Compose就内置推导了。更意外的是,它顺带解决了高对比度模式下的色块溢出问题——因为Composable默认响应`isInHighContrastMode()`,而View体系里得手动监听`UiModeManager`再调`getNightMode()`。不过?有个坑:Compose的`DateTimePicker`在折叠屏双屏展开状态下,屏幕阅读器会把左右两个日历格子当成同一焦点区域,读成“11月日历 日历”,重复两次。我提了issue #12987给JetBrains,至今没回。


  我知道有人会觉得——等产品上线后再补无障碍文档就行。


文章配图,仅供参考

  去年十一月,我们按这个思路给医疗AI问诊系统补文档,结果上线第三天就有视障用户投诉:问卷页面第7题的多选题组(带图标+文字)被读成“选项一图标 选项二图标……”而非“已婚 图标、离异 图标”,原因是开发用SVG作为``的`src`,而`alt`属性值写成了`"icon"`硬编码。设计师说“图标一眼就能看懂”,工程师说“SVG没法批量注入aria-label”,测试同学说“我们用的是Chrome DevTools模拟,没开NVDA”。直到用户打来电话,带着浓重方言说“医生,你们那个‘打钩框框’我摸不到啊”,我才连夜扒出整个Icon组件库的137个SVG文件,逐一手动加`aria-labelledby`引用旁侧隐藏`已婚`。那一晚改了42处,漏了11处,第二天早晨收到第二通电话:“那个离婚的,还是没声音。”——我打开网页源码一看,第52行SVG的``后面,缺了`aria-describedby="label-52"`,因为那个SVG是外包公司三年前传的,`#icon-divorce`本身没id,只有class名。这种链式失效,在纯View体系里太常见了。


  新技术未必完美。


  我认为Jetpack Compose在无障碍语义生成上,比Flutter的SemanticsTree更诚实——Flutter常偷偷包裹一层`Semantics`导致焦点层级混乱,而Compose要求开发者明确用`Modifier.semantics{}`声明意图。但它的局限也很刺眼:不支持`accessibilityPaneTitle`,这意味着分页Tab切换时,屏幕阅读器无法告知“当前在‘用药记录’页”,只能报“列表”。我试过用`LocalView.current.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)`强行注入,结果在Android 14 DP2上触发ANR——系统认为这是滥用无障碍通道。这事儿,我暂时没法儿教新人写进文档。


  我还在等Android官方给出`PaneTitle`的正式API。

(编辑:站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!