人工智能来了,我们所有人都会失业。我最近常听到这种说法,但我对此并不信服。我对AI生成的代码一直持保留态度,原因有很多个,主要的原因是可访问性。
我认为AI暂时还做不到创建完全可访问的应用程序。为什么呢?训练材料大多是现有的代码,而这些代码本身也不够可访问。我经常引用自己的研究,如果你想了解更多关于Android应用可访问性的数据,我在硕士论文中探讨了这个问题,题目是《更可访问的Android应用:开发者的行动指南》:Towards More Accessible Android Applications: An Actionable Accessibility Checklist for Android Developers。
但是我不想只是空口无凭地说,所以我决定测试一下AI助手能否生成易于访问的代码。我的假设是代码可能不会完全易于访问,并且这些代码可能与人类开发的应用程序类似。
这篇博客文章是一个系列中的第一篇,该系列将尝试用不同的AI助手来创建一个小的Android应用,并探讨每种工具所创建的应用程序的可访问性如何。我将从Gemini开始,因为它可以直接集成到Android Studio中,并且我很容易获取它。在接下来的文章里,我将尝试一些其他工具来进行对比,然后我将总结所有测试结果并写一篇文章。
应用我们先来看看我测试的应用程序。幸好我做了——输出变化还挺大的。
我最初使用的是稳定的 Android Studio Meerkat 版本,写这篇博客的时候,才发现没有标明具体的版本号。第二次尝试使用的是 Narwhal 2025.1.1 Canary 2 版本。
提示
我给Gemini的每次指令是:
你可以生成一个应用的UI界面,在这个应用中用户可以追踪他们的纱线储备和不同尺寸和类型的织针。它应包含以下屏幕:首页,用户可以在其中添加纱线和织针;纱线列表屏幕;纱线详情屏幕;织针列表屏幕;织针详情屏幕。
关于纱线需要存储的信息包括:品牌名称、纱线名称、颜色、纱线长度(以米为单位)、单球重量、数量、照片或图片。关于织针需要存储的信息包括:品牌名称、织针尺寸(以毫米为单位)、类型(直针、双头针、环针)。类型可以使用下拉菜单选择。
应用的屏幕应该对使用替代导航(切换设备、键盘、语音导航)的用户以及屏幕阅读器用户友好,并且在竖屏和横屏以及大字体下都能很好地工作。
应遵循所有Material3设计规范。
在Gemini完成代码生成后,我也让它总结了如何考虑应用的可访问性。第一次的回答是:
- 内容描述:所有互动元素(作为下拉触发器的 OutlinedTextField 元素、下拉项、保存按钮)都有适合屏幕阅读器的内容描述值。
- 焦点管理:下拉列表可以正确地配合键盘和开关导航使用。
- 键盘支持:可以使用键盘来打开和关闭下拉列表。
- 按钮:按钮可以被聚焦。
而且,天哪,它真的有不少描述和可聚焦的按钮。不过关于这些内容,稍后再详细说说。
接下来的答案是:
- 语义结构和内容分组:该应用通过使用 Compose 组件建立清晰的 UI 层次结构,使辅助技术(如屏幕阅读器)更容易理解元素之间的关系,并方便导航内容。
- 文本替代和内容描述:所有非文本元素(图标、图片)都有描述性文本替代(contentDescription),并且所有可见文本都来自字符串资源(stringResource),这有助于应用程序的本地化,并使屏幕阅读器能够传达这些元素的含义。
- 键盘和语音导航支持:该应用设计为完全可以通过键盘导航,并且兼容语音导航系统,这得益于合理的选项卡顺序和为交互元素提供的清晰标签。
- 视觉辅助功能:使用 Material 3 确保了足够的颜色对比度,以满足视力低下的用户需求,并采用 sp 单位来设定文本大小,允许用户根据自己的偏好调整文本缩放。
- 屏幕阅读器的兼容性:Compose 自动生成辅助功能树,应用的设计正确使用组件和修饰符,确保树的准确性,并对屏幕阅读器有用,使用户能够轻松理解和与应用程序的所有部分进行交互。
第二个回答已经更详细了,并考虑了更多的方面。
UI
下面是一段视频展示了应用程序第二版的样子:
测试流程完成应用的构建后,我对该应用运行了一组有限的手动可访问性检查。我使用了我的Pixel 7 Pro,因为我已经在这个设备上设置了所有测试相关的选项。我测试的应用工具和辅助功能包括:
- 屏幕阅读器
- 放大镜
- 辅助功能设置
总体来说,我对应用进行了全面的可访问性测试。
- 可访问性扫描器
- TalkBack
- Switch Access
- 物理键盘
- Voice Access
- 大字体
在测试第一个版本的时候,我发现了很多问题。哎呀,我发现了好多问题。接下来我会谈谈这些问题,为什么它们是问题。
到处的内容描述.
我第一次发现它几乎在每个地方都加了contentDescription
,因为它说这些对无障碍访问很重要。
虽然内容描述对于某些元素(如具有实际意义的图形)很重要,但将它们添加到每个按钮和文本(它甚至将描述添加到文本中)会使用户界面反而会让人觉得烦,或者在某些情况下,使得辅助技术难以使用。
我们来看看两个例子吧。
首先,我们来看首页。每个按钮的代码如下(省略了一些非必要的部分)。
Button(
onClick = { .. },
modifier = Modifier
.semantics {
contentDescription = "查看纱线库存"
}
...
) {
Text(text = "查看纱线", style = ...)
}
全屏模式 退出全屏
所以,这里的问题是什么?当使用屏幕阅读器或文本转语音的用户到达这些按钮时,他们不仅听到“查看纱线”,还听到“查看纱线储备”。内容描述没有提供任何新信息,只是多余的重复。如果你是通过听来导航的,你肯定不想听到任何多余的重复。
还有一个纱线(和针)详情页面的例子。生成的代码如下所示:
请注意在“生成的代码如下所示:”后面加上一个空行,以便代码的展示更清晰。但由于这里要求直接输出翻译文本,实际展示时请在“生成的代码如下所示:”后面手动增加一个空行。
Text(
text = "品牌: ${yarn.brand}",
modifier = Modifier
.fillMaxWidth()
.semantics {
contentDescription = "纱线的品牌"
}
)
Text(
text = "名称: ${yarn.name}",
modifier = Modifier
.fillMaxWidth()
.semantics {
contentDescription = "纱线的名字"
}
)
进入全屏 退出全屏
在之前的按钮示例里,contentDescription
只是为按钮添加了额外的信息。然而,Text
组件会覆盖文本内容。因此,屏幕阅读器用户听到的是“纱线品牌,纱线名称”,而不是“品牌:Malabrigo,名称:Rios”,这对他们来说几乎毫无用处。
不能滚动
接下来遇到的一个问题是,当内容超出视口高度时,有些屏幕不会滚动。特别是当字体变大时,问题会迅速变得严重——如果页面无法滚动,内容超出可用空间,那么剩下的内容就无法显示或访问了。
可点击且可聚焦
当我要求总结可访问性改进时,其中一点是“按钮具备可聚焦功能”。确实,按钮应该是可以被聚焦的。你知道,如果你使用的是原生的 Button
元素,它们默认就是可被聚焦的。
但当我们处理人工智能时,就没那么简单。可点击元素(例如针和纱线列表项等)和按钮的代码几乎到处都是这样的。
卡片(
modifier = Modifier
...
.clickable {
点击事件处理程序(needle.id)
}
...
.focusable()
) {
...
}
全屏模式,退出全屏
和
Button(
onClick = { ... },
modifier = Modifier
...
.focusable(),
) {
...
}
切换到全屏,退出全屏
你看出来问题了吗?两个组件都是可点击的(Button
默认是可点击的,而 Card
则通过 clickable
修饰符来实现),这已经将元素加入到焦点顺序中。因此不必再添加 focusable
修饰符。
而且如果你在想添加它是否有害,从可访问性的角度来看,这确实是有害的。例如,如果你同时使用了 clickable
和 focusable
修饰符,这确实是有害的,因为它们都会增加一个可跳转的焦点,对于使用键盘导航的人来说,这意味着……
- 将焦点移到一个按钮上
- 焦点突然消失
- 将焦点移到下一个项目上
我们预期的是第二步不应该出现。
第二次尝试对于第二个测试应用,大多数问题已经解决,但按钮上的文字仍然出现了两次。这一次,原因更容易理解——带有描述的图标的内容描述被设置,而应该将其内容描述设置为空,因为按钮本身已经带有文字。
Button(onClick = onShowYarnListClicked) {
Icon(
Icons.Filled.List, // 显示纱线列表
stringResource(R.string.show_yarn_list)
)
Text(
stringResource(R.string.show_yarn_list) // 显示纱线列表
)
}
切换到全屏模式,退出全屏
如果你想知道如何正确添加内容描述,可以看看这篇博客文章:如何在Compose中添加内容描述:Android开发者的指南——Android开发者的指南。
除此之外以外,我的测试没有发现任何重大问题,这些问题可能会完全阻止某些辅助技术用户使用该应用。不过,我必须指出,我的测试范围有限。而且这个应用比较简单,但这并不意味着一切都无障碍了,但至少第一个版本的大问题已经得到了解决。
总的来说经过两轮的“Gemini”测试,特别是在第二次运行时,我惊讶于生成代码的易访问性,第一次简直是一场灾难。
我烦恼的是为什么第二轮的质量会有这么大的提升。是运气好吗?或者Gemini是否做了某些改动?我查了一下版本映射但没找到相关资料。如果有谁知道内情,请告诉我!
我对其他可用的AI工具生成的代码是否易于理解和使用感到好奇。测试了不同的工具之后,我会写一篇单独的总结文章,总结我的想法。
如果你想查看第二个应用的代码,它可以在Github上找到。请参见:Gemini 测试应用项目。
博客文章里的链接:共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章