包容性移动应用开发教程-一-

76 阅读1小时+

包容性移动应用开发教程(一)

原文:Developing Inclusive Mobile Apps

协议:CC BY-NC-SA 4.0

一、可访问性

我对可访问性的兴趣始于 2010 年,当时我是一家小型苹果经销商的经理。在科技零售行业工作的一个很大的好处是,你可以在科技之旅的不同阶段接触到各种各样的人。有些客户会问一些原创性的问题,需要进行大量的研究才能找到正确的答案。其他人以前从未接触过你或我可能称之为“计算机”的任何东西,并且是从最开始开始。

2010 年 6 月,苹果发布了 iPhone 4。从那以后,我开始注意到,到店里来的顾客中,使用英国手语(BSL)作为第一语言的人数显著增加。从与其中一些客户的互动中,可以清楚地看出这是为什么:随着 iPhone 4 的发布,苹果也发布了一个全新的功能——face time。

FaceTime 和其他类似的视频通话功能对我们使用 BSL 的客户来说是一个不可思议的可用性改进。FaceTime 只是现代智能手机和之前的座机电话众多辅助功能中的一个。

电话和无障碍创新

包容性技术的一个目标是为所有用户创造可比较的体验,这个话题我们将在第二章中再次讨论。亚历山大·格雷厄姆·贝尔没有包容性思维的优势来指导他的发明。因此,环境还没有准备好让他在设计电话时将可访问性放在首位。在接下来的几年里,我们必须努力增加辅助技术。许多技术已经被添加进来,比如我们很快会谈到的聋人电信设备。短消息服务(或 SMS)、语音识别系统和视频通话都是电话的进步。虽然这些辅助技术为残疾人带来了改善,但这些增加并不是无缝的。这款手机有着悠久的历史,它让有特殊需求的人更容易使用。今天,手机仍然引领无障碍创新。

自从将近 150 年前发明电话以来,我们大多数人已经能够按计划使用电话与隔壁房间、隔壁国家或全球各地的朋友、家人、企业通话。考虑一下,如果这还不是事实的话,你主要的,或者唯一的交流方式是手语。这立即使电话变得无用。电话是一项无处不在的发明,但它以一种单一的媒介——音频——来呈现内容。创新帮助我们这些听不见的人让手机变得更容易使用。

聋人用电信设备

聋人电信设备通常也称为 TDD、TTY、文本电话或迷你通信。它是一个 QUERTY 键盘和电传打字机显示器,发明于 20 世纪 60 年代,连接到固定电话(图 1-1 )。有了这些附加功能,TDD 允许语言或听力受限的人输入他们的对话。对话可以被引导到其他 TDD 用户,或者被引导到将对话转发给非 TDD 用户的运营商。

img/486920_1_En_1_Fig1_HTML.jpg

图 1-1

聋人用电信设备的一个例子

虽然 TDD 对许多人来说是一个必不可少的工具,但它并不等同于电话。如果你曾经使用过这些服务中的一种,你会知道与标准电话相比,这种交互更慢、更笨拙,就像你通过口译员用外语进行对话一样。TDD 是可访问的,但它不是包容性的。

视频通话

如今,FaceTime 是一项我们都认为理所当然的技术。我们大多数参与软件开发的人几乎每天都会使用某种形式的视频通话系统——Skype、Google Hangouts、Zoom 或任何其他系统。但是,十年前,能够以高质量的视频即时看到世界上任何地方的任何人,并与他们交谈是非常开创性的。然而,对于我们的聋人和重听客户来说,这不仅仅是突破性的。这对他们的交流能力是一种转变。签署对话的能力最终使电话成为一种可比拟的体验。

FaceTime 之所以没有成为苹果的产品,是因为苹果打算为手语用户提供一个优秀的辅助工具。苹果开始创造一款适合所有人的伟大产品。通过确保它为每个人工作,并在整个项目中考虑可访问性,苹果为一个特定的受众提供了超级服务。

移动创新

手机里充满了像 FaceTime 这样的辅助功能。谷歌助手和 Siri 快捷键降低了对准确性的要求。这有助于有学习困难的人。它还减少了帮助解决运动问题所需的触摸次数。屏幕时间和 Safari Reader 有助于最大限度地减少分心——非常适合注意力缺陷障碍患者或有精神健康问题的人,他们可以在焦点中找到解脱。听写、拼写纠正、预测文本、语音备忘录、提醒振动、第三方键盘和外部键盘支持都是辅助技术的例子。您很有可能每天都在使用这些工具,而从来没有考虑过它们是一个辅助功能。

考虑一下我们之前讨论过的用于聋人的电信设备。发明者需要某种方法来允许数字文本通过电线传输。他们的最终发明是调制解调器。没有调制解调器,我们的许多现代数字社会就根本不可能存在。下一次,当你带着一个滚轮箱或一辆童车出现在街道的拐角处时——下降的路缘最初是为了帮助轮椅使用者而设置的,这意味着你不必将沉重的物品举到街道的高度。强大的可访问性不应该是一个只有少数人使用的模糊特性。在最好的情况下,易访问性应该是你正在创建的产品或服务的一等公民,应该让每个人受益。

显然,无障碍不仅仅是让残疾人受益的事情。它为所有用户提供了更广泛的可定制性。虽然残疾用户可能受益最大,但是您的每一个用户都会从您给予可访问性的考虑中受益。在最好的情况下,可访问性是对您的每一位客户的包容。我们将在第二章中详细介绍这一点。现在,让我们对我们所说的残疾,尤其是数字环境中的残疾,有一个更深入的了解。

什么是残疾?

2019 年 1 月,一张照片在社交媒体上被广泛分享(图 1-2 )。这张照片展示了一个平常的女人走在市中心的街道上,忙着自己的事情。然而,这位女士有两个特点引起了脸书用户的评论。这位女士用的是智能手机,没什么不寻常的,但这位女士也有一根白色的拐杖来帮助她在城市中导航。

img/486920_1_En_1_Fig2_HTML.jpg

图 1-2

一个人使用拐杖和智能手机。发布到脸书,标题是“如果你能看到问题所在,就说我看到了”

自第一次世界大战以来,白手杖一直被用作帮助盲人和部分失明者的工具,许多人使用它来帮助他们通过感觉周围的街道来寻找障碍和线索,如触觉铺路,从而在建筑环境中导航。然而,手杖的主要用途之一,对于我们这些不使用它的人来说,可能不会立即显而易见;暗示就在手杖的颜色里。白色手杖的确是白色的。因为它们是白色的,对我们这些看到它的人来说,它们是一个明确的指示,持有它的人可能看不到我们。这给了我们一个提示,作为司机,我们要格外小心,作为行人,我们要确保给行人留出通过的空间。

也许这就是张贴到脸书的照片中的女士的情况。也许她视力不好,使用拐杖主要是为了向其他行人暗示她可能看不到他们。可能她确实使用她的拐杖来感觉她周围的建筑环境,因为她看不到远处的物品,但她的眼睛仍然具有更近的视觉,因此可以继续使用她的电话。

我不认为任何阅读这本书的人会像许多脸书用户一样,质疑这位女士的能力或缺乏能力,主要是因为你可能在移动领域工作,知道她可以做出大量的显示调整来改善她的体验,并允许她使用她的智能手机。也许她启用了大文本或缩放功能。也许她正在使用反转的颜色或增强的对比度。她甚至可能根本没有看屏幕——她可能正在使用屏幕阅读器,并且屏幕幕布已经打开,这只是使用手机时的自然方式。不去问别人,是不可能理解别人的经历的。如果你想真正了解别人是如何使用你的应用的,这正是我的建议——问他们。

所有这些都是在说——残疾并不像生活中的任何事情一样,仅仅是一种二元状态。不可能把世界分成两类——残疾人和健全人;或者,在我们的先例中,失明和视力正常。介于两者之间的是很大一部分人——从我们这些不得不戴老花镜完成特定任务的人,到我们这些因白内障、色盲和其他疾病而完全没有光感的人。随着时间的推移,视力障碍因人而异,所有的残疾也是如此。我相信我们都知道,并不是所有的残疾都是可见的。

那么,如果残疾是一个广泛的范围,我们如何定义它?强调我认为残疾的含义的最佳方式是使用世界卫生组织的定义。1980 年,世卫组织对残疾的定义如下:

在健康体验的背景下,残疾是指以人类认为正常的方式或在正常范围内从事某项活动的任何限制或能力缺乏(由损伤导致)。 1

世界卫生组织,1980 年

换句话说,他们将残疾定义为一个人的特征,一种使残疾人不同于我们其他人的东西,并且不能做我们合理期望“正常”人能够做的事情。我认为我们可以将残疾定义为“能力的限制或缺乏”但最后一部分出现了问题——“被认为是人类正常的范围。”这里的“正常”一词提出的问题比它回答的问题更多——什么是正常人?我们会期望这个虚构的正常人做什么?谁决定什么是正常的?如果我不符合正常的定义,我应该担心吗?所有这些问题的答案都很简单——没有这样的事情。人类是没有“正常”的。我不想听起来像学龄前儿童电视节目——我们都有自己独特的方式。

今天访问世界卫生组织的网站,你会看到一个更新的定义:

残疾不仅仅是一个健康问题。这是一个复杂的现象,反映了一个人的身体特征和他或她所生活的社会特征之间的相互作用。克服残疾人面临的困难需要采取干预措施,消除环境和社会障碍。 2

世界卫生组织

这个定义认为残疾不是人的问题,而是我们所建立的社会的问题。这个定义承认每个人都是不同的,有不同的能力、知识和技能,不同是正常的。因此,如果有人与我们社会的某个方面作斗争,这不是这个人的问题。相反,这是允许这种情况发生的文化问题。这一定义还承认,残疾不在于某人能否使用台阶进入建筑物。相反,它是关于我们赖以建立社会的系统,例如,如果我们让有学习障碍的人填写一个大表格,我们可能会让他们感觉如何,或者有心理健康问题的人可能会觉得被一个规定的系统所困。这被称为残疾的社会模式。

主要少数派

被认为有残疾的人是少数。但是他们一起构成了欧洲和北美最大的少数民族之一。在美国,估计有 27%的人有残疾,也就是 8530 万人。这使得残疾人数量相当于人口最多的三个州的总和。在英国,22%的人报告有残疾,接近 1400 万人。 4 全球有超过 10 亿人患有残疾,约占全球人口的 15%。 5 贵组织的设备支持政策很有可能涵盖市场份额远低于残疾客户总数的设备。

读到这里,我希望我已经让你相信了考虑不同能力的用户的重要性。因此,我敢肯定,你个人工作的可及性质量会高得多。然而,对残疾客户的最大影响将会发生,因为您的企业和您的同事与您一样坚信创造良好的无障碍体验。在接下来的部分中,我们将介绍实现这一点的方法。

易访问性的商业案例

最终,可访问性的理由很简单——这是应该做的事情。因为你的客户的能力而歧视他们是错误的。但是,我意识到,如果你是一个经理,或者你正在为一个业务经理的可访问性增加关注的案例,那么你需要包括其他的考虑。

美国国家残疾人组织估计,残疾人的可自由支配支出超过 2000 亿美元。 6 在英国,残疾人及其家庭的消费能力被称为“紫镑”紫色英镑被认为是企业的一项重要支出。有证据表明,不考虑数字无障碍的公司会因为让残疾人选择替代服务而失败。在英国,紫色英镑价值约为 2650 亿英镑或 3360 亿美元。 8

如果额外的 2000 亿美元市值对你的企业来说还不够,还有一个相当大的法律大棒,可能会导致巨额罚款和长期的声誉损害。

无障碍法律

与任何法律一样,各国在无障碍法律上的差异也很大。许多国家根本没有关于无障碍的法律。即使有法律,也往往只涉及政府或公共部门。有时,这些将是前数字法律通过公约粗略调整,以适应数字渠道。许多法规没有明确关注数字无障碍;相反,它们是更普遍的不歧视法律。你应该寻求法律建议,以确定哪些规则适用于你所在的市场,以及如何适用。

在这一节中,我将介绍两个主要地区的数字无障碍法律,我们大多数创建移动应用的人都必须遵守这些法律。本节旨在提供高水平的概述,而非法律建议,因此如果你认为这些法律可能适用于你的企业,我建议你寻求专业意见。

美国

美国拥有世界上最古老的无障碍法律之一。1990 年出台的《美国残疾人法案》(简称 ADA)。10

《美国残疾人法案》涵盖了政府确保供应商和政府提供的服务(如学校)无障碍的要求。私营部门包括有形的“公共住宿场所”——餐馆、剧院和你我的商店。ADA 对数字内容并不明确。但是支持《美国残疾人法案》的司法部坚持认为《美国残疾人法案》也足够宽泛,可以管理数字体验。在 2019 年的一个标志性案件中,达美乐披萨选择挑战这一论断。达美乐向最高法院提起诉讼,声称 ADA 不适用于他们的披萨订购应用。最高法院驳回了达美乐的诉讼。这开创了一个先例,意味着对移动可访问性的法律要求不是一个灰色地带。其他家喻户晓的名字,如国家篮球协会、网飞和碧昂斯都违反了 DOJ 法院对美国残疾人协会的裁决。

欧洲

2018 年制定的欧洲无障碍法案 11 是一部更加现代化的立法。EAA 将整个欧洲的无障碍立法作为参考。它也从美国反倾销协定中得到启示。目的是在全欧洲实现数字无障碍的无障碍要求标准化。

EAA 没有明确规定移动或数字服务的整体无障碍标准。它坚持定义类别的移动可访问性标准。其中包括电子商务、银行、与客运相关的软件服务,以及作为智能手机或智能手机操作系统一部分的软件。

要求因应用的业务类别而异。总之,一些共同的要求包括

  • 提供灵活的放大倍率、对比度和颜色。

  • 提供精细电机控制的替代方案。

  • 通过一个以上的感官渠道提供信息。或者以设备可以在替代的感觉通道中呈现的格式提供信息。

  • 为非文本内容提供替代内容。

  • 为辅助技术提供一致的互操作性。

倡导无障碍

提高应用可访问性的最佳方式之一是在组织内倡导可访问性。当 UX 给你发送新的设计,产品要求一个新的特性,或者你的团队正在提炼故事,所有这些都是提倡的好时机。

不要批评别人的工作。从我的经验来看,同事们确实很在意可及性,希望做得更好。有时他们缺乏这样做的知识和专业技能。当你看到可访问性已经被考虑时,支持工作;当你知道某样东西将很好地满足不同需求的用户时,祝贺工作。提出一些小建议,这些小建议将有助于改善体验。随着时间的推移,你会发现你的团队会接受这一点,并开始从易访问性优先的方法来考虑。

如果您的组织有多个面向客户的软件团队,您可以考虑建立一个易访问性倡导者网络。鼓励每组中的某个人参与进来。包括 UX、产品,也许还包括管理。通过空闲频道分享知识和问题。在某些情况下,找到培训预算是可能的,这提供了您可以向您的团队逐级传达的洞察力。根据你所学到的知识,考虑为其他同事举办培训课程。分享下一节中的一些活动有助于打破僵局。

展示可访问性

让同事和经理相信可访问性很重要,并让他们明白为什么它对您的客户很重要的一个有效方法是模拟您的客户可能正在经历的一些情况。通过这种方式,同事可以直接体验使用不同功能体验您的应用可能会是什么样子。不过,做这些练习时要小心。目的是让您对客户的体验有所了解。人们从这些练习中得到的有时是对残疾的怜悯和恐惧。

我收集了一些练习,提供了某些能力的粗略估计。对于这些活动,选择不同的日常智能手机任务。或者,为了使其与您的组织更相关,从您的应用中选择一个广泛使用的流程。要知道,你可能已经对你的应用更熟悉了,因为它是你做的。每次都让任务变得不同,以避免过于熟悉流程。

Simulating Blindness

iOS 有一个辅助功能,可以与其内置的屏幕阅读器 VoiceOver 一起使用,允许阅读器的用户维护隐私。这项功能被称为“屏幕幕帘”,它可以关闭显示屏上的图像,同时保持触摸屏处于活动状态。由于屏幕阅读器用户已经大声朗读了他们个人设备的内容,这可以防止他们无意中以可视方式共享个人内容。弱视或失明的用户可能意识不到私人内容是可见的,因此保持屏幕打开几乎没有好处。此外,禁用它可以增加隐私和电池寿命。Screen Curtain 为我们提供了一个绝佳的机会,让我们了解在没有视觉反馈的情况下使用智能手机会是什么样子。

在这项活动中,选择一项你可能用手机完成的日常任务。添加日历事件是一个不错的选择,或者为了使其与您的组织更加相关,您可以从您的应用中选择一个典型的流程。启用 VoiceOver–执行此操作之前,请阅读第六章中的“使用 voice over 导航”一节。然后用三个手指轻敲屏幕三次来启用屏幕幕帘。

现在,使用屏幕阅读器来导航手机并完成任务,而无需查看屏幕上的内容。虽然那些每天使用屏幕阅读器的人可能比一般的工程团队更熟练,但这应该会让你了解当语音是唯一的反馈时,智能手机使用的哪些方面更难。如果你是作为一个小组练习来做的,这也会让你了解嘈杂的环境是如何让屏幕阅读器的使用变得令人沮丧的。这相当于屏幕阅读器用户在你的屏幕上挥手。

股票 Android 没有一个等效的功能。但一些三星设备有一个名为黑屏的设置,这与启用对讲有相同的效果。

Simulating Attention Disorders

对于这项任务,你需要一些小气球或软球。从智能手机或应用的标准流程中选择一项你每天都要做的工作。你的任务是完成这个流程,同时保持气球或球在空中。虽然这种类比可能有点夸张,但这应该会让你了解到,对于有注意力缺陷障碍的客户,或者作为小孩子的父母,使用你的应用是多么容易。

Simulating Visual Impairments

来自英国的皇家国家盲人研究所制作了一款名为 EYEWARE 的应用。苹果应用商店 12 或谷歌 Play 商店都有免费提供。EYEWARE 与谷歌 Cardboard 配合使用效果最佳,但如果你手头没有的话,它也能工作。

RNIB 和有视觉障碍的人一起开发了 EYEWARE,以模拟有视觉障碍的人体验世界的感觉。该应用允许你从几种不同类型的损伤中进行选择——从色盲到白内障、青光眼等等,包括每一种的变体。尝试这些设置,并以不同的视觉水平完成您选择的一项或多项任务。例如,考虑一下色盲对颜色的使用是如何变化的,以及对于白内障来说,较大的文本是如何重要的。

摘要

  • 有时候,我们制造的技术会排斥有特殊能力的人。我们可以通过添加辅助功能来改善这些。但是这些附加品往往感觉就是附加品;它们不是无缝的。

  • 在下一章,我们将讨论数字包容。这是可访问性的最终目标——让技术对每个人都有宾至如归的感觉。

  • 残疾不是一种二元状态。我们都有能力,也有能力的极限。当我们建造的东西不适合拥有特殊技能的人时,残疾就发生了。

  • 在构建你的应用时,考虑人们的不同能力有一个很大的商业案例,一个 2000 亿美元的商业案例。这还只是在美国。您的业务也将受到国际无障碍立法的约束。如果你不遵守这些法律,你将受到巨额罚款和名誉损害。

我们将在下一章继续关注无障碍技术的背景。但是我们将不再把可访问性作为额外的考虑。相反,我们会考虑包容性,以及如何让所有用户都感受到自己是我们应用的一部分。

Footnotes 1

https://download.microsoft.com/download/b/0/d/b0d4bf87-09ce-4417-8f28-d60703d672ed/inclusive_toolkit_manual_final.pdf

  2

www.who.int/topics/disabilities/en/

  3

www.census.gov/content/dam/Census/library/publications/2018/demo/p70-152.pdf

  4

www.gov.uk/government/collections/family-resources-survey--2

  5

www.who.int/disabilities/infographic/en/

  6

www.dol.gov/odep/pubs/fact/diverse.htm

  7

http://clickawaypound.com/cap16finalreport.html

  8

www.barclayscorporate.com/client-experience/client-benefits/supporting-economic-growth/

  9

www.w3.org/WAI/policies/

  10

www.ada.gov

  11

https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=COM:2015:0615:FIN

  12

https://apps.apple.com/us/app/eyeware/id1169994271

  13

https://play.google.com/store/apps/details?id=com.transportsystemscatapult.EyeWarePro&hl=en_US

 

二、数字包容

在这一章中,你会发现一些关于包容性思维的历史以及这意味着什么。我们将涵盖支持这种思想的基本原则,并讨论在创建软件时应该考虑的事情,例如记住用户是真实的人的重要性。我们将涵盖任何一个软件工程师所能拥有的最重要的技能,它与为你的工作感到自豪密切相关。

包容性思维的历史

数字包容植根于建筑和产品设计。在创建移动应用的过程中,良好的设计是必不可少的。但是一个应用的可访问体验的很大一部分仍然是由我们这些不是设计师的人创造的。数字共融意识到,包括但不限于设计师在内的每个人都有责任鼓励更加无障碍的互动。

即使你不是一名设计师,我也认为值得我们花时间了解一下这个设计学院的背景。通过这种方式,我们可以了解所犯的一些错误以及修复这些错误的步骤。另外,如果你是一名工程师,你的工作就是将设计变成现实。因此,了解影响这些设计的作品将有助于你实现它们。

通用设计

数字包容植根于通用设计,这是一场始于 20 世纪 60 年代末的运动,它导致了我们今天在身边看到的许多常见的无障碍改进。建筑师和设计师罗纳德·梅斯创造了通用设计这个词。他用它来描述为尽可能多的人设计可用产品和建筑环境的概念,同时保持美学上的愉悦。

同为建筑师的塞尔温·戈德史密斯本人也是一名轮椅使用者,他通过倡导现在无处不在的下凹式路缘或路缘切割推进了通用设计的概念(图 2-1 )。路缘切口使轮椅使用者或行动不便的人能够比标准的凸起路缘更舒适地过马路。下降的路缘也是通用设计如何帮助尽可能多的人的最好例子。虽然最初的目的是提高轮椅使用者的机动性,但它也允许父母使用婴儿车,旅行者使用行李箱。

img/486920_1_En_2_Fig1_HTML.jpg

图 2-1

提供通向街道的无台阶通道的路缘切割

通用设计是建筑师、产品和工业设计师用来指导他们实现罗纳德·梅斯最初目标的一系列原则。1997 年,北卡罗来纳州立大学聚集了一些通用设计的主要倡导者,包括罗纳德·梅斯本人。他们一起定义了通用设计的七个原则。 1 这些是

  • 公平使用

  • 使用的灵活性

  • 简单直观的使用

  • 可察觉的信息

  • 误差容限

  • 低体力劳动

  • 接近和使用的尺寸和空间

我在这里非常简要地总结了这些原则的内容。我还简要介绍了每个原则如何适用于手机。这里的一些概念可能是新的,但是我们将在后面的章节中讨论所有的概念。

公平使用

让设计吸引所有用户。这个设计应该对具有不同能力的人有用并且有市场。避免隔离或侮辱任何用户。尽可能为所有用户提供相同的体验。如果你必须提供另一种体验,那就把它等同起来。考虑所有客户的隐私、安全和保障。

在移动环境中,这可能意味着避免使用不符合 WCAG 2.1(第三章)4.5:1 对比度准则的颜色。 2 此外,确保你的应用与对讲、画外音等辅助技术无缝配合(图 2-2 )。

img/486920_1_En_2_Fig2_HTML.jpg

图 2-2

VoiceOver 导航 iOS 的天气应用

使用的灵活性

您的设计适应了广泛的个人偏好和能力。提供选择,方便用户,并适应他们。

这在移动设备中的例子包括支持不同的文本大小。允许多种文本输入方法,如屏幕键盘、听写(图 2-3 )或外部键盘。两个平台都为您的客户提供各种定制设置;尽可能尊重这些。

img/486920_1_En_2_Fig3_HTML.jpg

图 2-3

谷歌的屏幕键盘允许通过听写输入

简单直观

无论用户的经验、知识、语言技能或当前的注意力水平如何,都要确保你的设计易于理解。消除不必要的复杂性。与用户的期望和直觉保持一致。适应广泛的读写和语言技能。以与其重要性一致的方式安排信息,突出最重要的信息。在任务完成期间和之后提供有效的提示和反馈。

在你的应用中坚持标准的设计语言,包括尽可能坚持系统提供的控件和约定。仔细总结信息,但如果客户想要了解更多信息,请允许他们深入了解细节。保持语言简单易懂。当你的应用需要用户输入时,你应该明确你需要什么信息以及在哪里。如果你的客户犯了一个错误,让他们很快改正。

可察觉的信息

你的设计应该有效地向你的用户传达必要的信息,不管环境条件或用户的感觉能力如何。使用不同的模式(图像、语言、触觉)来重复呈现基本信息。在前景和背景之间提供足够的对比——我们将在第三章中详细介绍。提供与感官受限者使用的各种技术或设备的兼容性。

为了在移动设备中满足这一原则,我们必须确保设备的屏幕阅读器或设备上可用的任何其他辅助技术可以访问所有内容。关于 Android 可访问性模型的第四章和关于 iOS 可访问性模型的第六章会给你一些工具。用多种方式展示你的内容。使用颜色、形状、图像、文本和布局的组合来使你的内容有意义(图 2-4 )。您的客户的屏幕阅读器会将文本内容转换为音频内容,但它不能将您提供的文本转换为图像。对于有价值的内容,可以考虑用其他方式提供,比如视频。

img/486920_1_En_2_Fig4_HTML.jpg

图 2-4

Android 结合了颜色、形状、文本和图像来传达意思

误差容限

将意外或无意行为的危害和不利后果降至最低。安排元素以最小化风险和错误:突出常用控件。提供危险和错误的警告。如果客户做出破坏性的改变,提前通知他们,并允许他们退出。如果你的顾客犯了一个错误,清楚地指出来,让他们毫不费力地修改。在承诺任何行动之前,让您的客户回顾他们的反应,并允许他们改变或回复。提供安全功能,这样破坏性影响就不会意外发生。

在移动应用中,这包括当你要求用户做出决定时,使用清晰简明的信息来说明每个动作的后果。给有害或破坏性的行为增加摩擦,并向客户提供反馈,告诉他们在做决定时会有什么样的结果。

低体力劳动

确保客户能够高效、舒适地使用你的设计,并尽量减少疲劳。尽量减少重复的行动和持续的努力。

你界面上的所有按钮都应该触手可及(图 2-5 ),尤其是在大屏幕设备上。提供应用常用区域的快捷方式,并在可能的情况下支持谷歌助手或 Siri 快捷方式。

img/486920_1_En_2_Fig5_HTML.jpg

图 2-5

常见功能的快捷方式位于屏幕底部,触手可及

接近和使用的尺寸和空间

最后一个原则最适用于物理项目。该原则规定,无论用户的体型、姿势或活动能力如何,都应该为接近、够到、操作和使用提供适当的尺寸和空间。使触及所有部件都很舒适,并适应手和把手尺寸的变化。

我们可以通过使我们的界面适应不同的屏幕尺寸和文本尺寸来满足这个指导方针。确保您的应用支持开关控制和开关访问,并允许键盘导航;此外,语音控制和语音访问(图 2-6 ),让您的客户几乎不用移动就能控制您的应用。任何交互元素都应该至少是 44px 的正方形,以便不坚持精细的运动控制。

img/486920_1_En_2_Fig6_HTML.jpg

图 2-6

Android 的语音访问功能允许在不触摸屏幕的情况下导航

这些通用的设计原则导致了许多我们认为是日常用品的产生。我们可能不认为这些产品中的许多是“可访问性”特性。考虑有声读物、自动门、高对比度标牌和柔性吸管。所有这些产品都是按照通用设计准则创造的。他们为许多能力不同的人服务,但也是对其他人的改进。这是我们应该在应用中努力实现的目标。我们的理想目标是创造一种包含所有人的体验。

通用设计考虑残疾问题,并考虑您可以通过修改设计来帮助有残疾的人,从而减少产品使用的障碍。减少障碍扩大了潜在用户的市场。然而,由于通用设计是在数字时代之前开发的,这种方法是为实体产品量身定制的。

包容性设计

包容性设计延续了通用设计的优势。它通常更适合数字交互。通用设计考虑到残疾,而包容性设计考虑到个人,倾向于更易接近的优先方法。包容性设计向前迈出了一大步,认识到残疾不是一种永久的二元状态,而是一种光谱。人们能力的不平等是很典型的,并且随着时间和环境的变化而变化。包容性设计通过将人们的需求视为永久的、暂时的、情境的或变化的来做到这一点。通过改善有特殊需求的人的体验并在第一时间考虑这些需求,我们可以将这种好处扩展到更广泛的人群,从而改善每个人在生命中某个时刻的体验。

数字无障碍顾问 Paciello Group 3 帮助定义了包容性设计的七个原则。他们设立了 inclusivedesignprinciples.org4来记录他们。这些原则是

  • 提供类似的经验

  • 考虑情况

  • 保持一致

  • 给予控制

  • 提供选择

  • 区分内容优先级

  • 增值

我在下面概述了这些原则以及它们如何应用于移动设备。

提供类似的经验

确保你的界面为所有人提供可比较的体验。允许人们在不破坏内容质量的情况下,以适合他们需求的方式完成任务。您可以在应用中提供音频描述或视频脚本。这将使你的原创内容易于访问。但这种替代是否抓住了原作的精髓和基调?移动交互有一种特殊的品质,让用户惊喜。你应该确保你的所有用户都能获得如此丰富的体验,即使他们使用的是辅助技术。

inclusivedesignprinciples.org 提供的一个例子是 Android live regions(图 2-7 )。实时区域是当内容改变时自动向辅助技术报告的屏幕区域。TalkBack 将读取该内容,而无需用户将焦点导航到该内容。iOS 没有实时片段功能,但您可以使用辅助功能通知自己创建一个。我们将在第八章中讨论这些。

img/486920_1_En_2_Fig7_HTML.jpg

图 2-7

“正确!”/“不正确的”屏幕区域是一个活动区域。TalkBack 会在内容发生变化时自动通知用户,而不会让用户失去焦点

考虑情况

人们在不同的情况下使用你的界面。确保你的界面给人们带来有价值的体验,不管他们的环境如何。

考虑在明亮的阳光下使用手机,音频和触觉反馈以及高对比度的颜色将有助于这种情况。在您的视频内容上提供字幕或隐藏字幕(图 2-8 )可以让父母在观看视频时降低声音,而不会打扰他们熟睡的孩子。

img/486920_1_En_2_Fig8_HTML.jpg

图 2-8

视频的字幕可以让人们在不打扰他人的情况下观看视频,也可以帮助有听力障碍的人

保持一致

使用熟悉的惯例,并始终如一地应用它们来促进熟悉和理解。这种一致性既适用于您的应用内部,也适用于您运行的系统。

不要在你的设计中重复发明轮子。当你通过使用 Android 和 iOS 为你提供的控件,站在巨人的肩膀上构建设计时,请随意对控件进行子类化,以添加你需要的功能或外观,但以这些为基础将会免费给你带来很多额外的东西。你的用户会有宾至如归的感觉,因为他们的交互会感觉很熟悉,苹果和谷歌已经为你提供了许多辅助功能。

给予控制

确保人们处于控制之中。您的客户应该能够以他们喜欢的方式访问内容并与之交互。不要禁止或禁用更改标准平台设置的功能,如方向或字体大小(图 2-9 )。此外,除非有办法控制,否则要避免未经用户同意的内容更改。

作为开发人员,有一些方法可以禁用一些辅助功能。例如,您可以创建一个不支持缩放文本大小的应用。这可能意味着你得到了一个像素级的完美设计,但它将极大地影响你的用户舒适地使用你的应用的能力。

img/486920_1_En_2_Fig9_HTML.jpg

图 2-9

iOS 动态测试风格的最小和最大设置。支持这些对您的客户来说非常重要,并且需要灵活的设计

提供选择

考虑为人们提供不同的方法来完成任务,尤其是复杂的或非标准的任务。完成一项任务的方法往往不止一种。你不能假设某人喜欢的方法是什么。通过提供布局和任务完成的替代方案,你为人们提供了适合他们和他们当时环境的选择。

一个很好的例子就是在 iOS 的邮件应用中删除邮件。我可以通过点击(图 2-10 )、滑动(图 2-12 )或长按(图 2-11 )来实现这一点。作为一名用户,这让我可以选择最快的应用使用方式。

img/486920_1_En_2_Fig12_HTML.jpg

图 2-12

通过滑动删除邮件

img/486920_1_En_2_Fig11_HTML.jpg

图 2-11

长按删除邮件

img/486920_1_En_2_Fig10_HTML.jpg

图 2-10

轻按删除邮件

区分内容优先级

通过在内容和布局中对核心任务、功能和信息进行优先排序,帮助用户关注它们。确定界面的核心目的,然后是实现该目的所需的内容和功能。当核心特性没有被清楚地展示和区分优先级时,界面可能很难理解。

逻辑地组织你的内容,用标题特征或角色来标记标题。当你启动电子邮件应用时,你不会看到可供选择的邮箱和文件夹列表。你会看到一个收件箱,因为这是最重要的功能。标准功能应该简单且始终可用。更复杂的动作应该是可能的,但不突出。让所有东西同时可用会导致界面混乱。考虑将高级控件放在辅助手势(如长按)之后。

增值

考虑功能的价值以及它们如何改善不同用户的体验。考虑语音、地理定位、摄像头和振动 API 等设备功能,以及与连接设备或第二个屏幕的集成如何提供选择。

这是包容性设计的领域,手机在这方面远远超过其他平台。移动设备充满了传感器和反馈模式。智能家居、屏幕或外部控制器等外部设备可以无线连接。两个平台上的拾取器控件都使用触觉来在事情发生变化时向用户提供触觉反馈(图 2-13 )。虽然这也是一种令人满意的体验,但对于有视觉障碍的客户来说,这是一种必不可少的反馈模式,可以帮助他们确定何时做出了改变。

img/486920_1_En_2_Fig13_HTML.jpg

图 2-13

在 Android 上设置闹钟。当在分钟/小时间隔之间移动时,提供触觉反馈

人物谱

微软是软件包容性设计的最大支持者之一。 5 微软推出了一款他们称之为人物角色谱的工具(图 2-14 )。人物角色谱帮助我们考虑包容性设计对使用我们软件的人意味着什么。

像包容性设计一样,我们将残疾分为永久性、暂时性或情境性。永久性残疾的一个例子可能是失去上肢。失去一只手臂会使许多日常交流变得困难,有些甚至是不可能的。对于这个人来说,改进你的应用可能意味着确保你所有的按钮都在握着手机的手的拇指容易触及的范围内。或者更好的是,增加语音控制功能。在这样做的时候,你也可以让你的应用对那些最近手臂受伤并使用吊带的人更有用。手臂受伤是暂时的损伤——至少我们希望如此。我们断臂顾客将在一个月左右恢复肢体的完全功能。有了这个改进,你也可以帮助新父母。新父母可能花很多时间用一只手,而他们用另一只手来抱或喂他们的婴儿,控制婴儿车,或握住一只手。在这个例子中,我们的新父母有情境障碍。一旦他们的孩子睡着或被交给另一个家庭成员,他们的第二条肢体就可以恢复使用。

对于这个例子,微软做了一些研究来强调这种思考方式如何给你的客户带来巨大的好处:

在美国,每年有 26,000 人患上肢缺失。但如果我们把有暂时性和情境性障碍的人包括在内,这个数字将超过 2000 万。

—微软包容性设计工具包手册 7

nine

img/486920_1_En_2_Fig14_HTML.jpg

图 2-14

角色光谱的例子

9

微软提供的这些例子也展示了视觉、听觉和语言角色谱的例子。盲人用户会感谢你考虑他们在没有视觉的情况下如何使用你的应用。这也将有利于最近做了眼部手术的人,或者正在开车而不能看设备屏幕的人。

考虑您的应用如何为聋人服务,将有助于患有耳部感染的人或在嘈杂环境中工作的人。一个使用非语言交流的人将会受益于同样的考虑,就像帮助像喉炎这样的暂时状况,或者像与带有浓重口音的人交流这样的情况。

New Spectrums

你的团队能创造人物角色谱的新例子吗?

考虑一下你的一个永久残疾的顾客。如果你为这些人改进你的应用,你会解决什么临时或情境场景?

考虑一个客户在野外的情况。你可以添加哪些功能来帮助这个用户?这对有暂时或永久损伤的人有什么帮助?一个患有焦虑症的客户怎么办?您可以做出哪些改进来为该客户提供更好的体验,这将如何惠及其他人?

数字包容

在一个敏捷的组织中制作软件不仅仅是实现一个设计师指定的屏幕。我们可以从包容性的设计方法中学到很多东西。但并不是所有这些都与我们这些不是设计师的人相关,而且很多并不直接适用于现代数字世界。

我们需要一种数字优先的包容性方法,一种构成更全面、更高层次信念的方法。一个认识到组织中每个人都有责任的策略,可以确保创建的服务适合尽可能多的人。拥有先进平台知识的开发人员是这一过程的重要组成部分。数字共融的一个重要部分是认识到残疾人虽然重要,但不是唯一想使用我们服务的少数群体。年龄、性别、教育、社会群体、收入和性取向等其他因素都会影响我们对技术的体验。我在下面总结了我对数字共融原则的建议。

移情作用的

考虑他人,认识到每个人都是具有不同知识、经验和能力的个体,并承认这使人们对你的应用的体验不同——可以说,这是数字包容性最关键的原则,我们将在自己的章节中讨论这一点。

环境形成的

并非所有使用你的应用或服务的障碍都来自人们的身体能力。包容就是把人的情况作为一个整体来考虑。这包括他们的技能,也包括其他因素:财务、性别、数字素养、心理健康和第一语言等等。要意识到所有这些因素都会影响人们使用你的应用的方式。

学会的

贵组织创建的软件反映了贵组织本身。想想一些社交媒体领袖的几乎自由主义的观点是如何导致几乎任何事情都可以发生的平台,包括有时的种族主义、选举干预和骚扰。组织中的每个人都可以在提高应用的用户可访问性方面发挥作用,并且有责任这样做。在下一节中,我们来看看我们所说的用户是什么意思,以及这些人是谁。

用户

在软件工程中,我们通常为我们的“用户”创造产品有时人们会引用数据可视化先驱爱德华·塔夫特的话,称人们为“用户”是我们和毒品贩子共有的习惯。不过,这可能也不是真的。我想,毒品贩子仍然称他们的顾客为“顾客”,因为他们就是“顾客”。真的只有警察和媒体才使用“用户”这个词我不打算监管你使用的语言,但是让我们来看看为什么我们应该对使用这个词有第二个想法。

个人

我不认为使用用户这个词有什么固有的错误;事实上,我在整本书中都使用了这个术语。问题是这个词经常隐藏了我们真正在为谁做软件——个人。你的每一个用户都是独立的个体,每个人都有自己的需求、能力、经验和对软件的要求。

使用“用户”这个词可能会导致陷入将用户视为一个群体的陷阱——一群在世界某个地方使用你的应用的人,一群你永远也不会遇见和了解的人。这种形式的“群体思维”导致了一种“一刀切”的解决方案,就像所有声称“一刀切”的事情一样,实际上没有人适合。

你最大的优点是别人都不是你。别人没有你的技能和经验。同理,你也没遇到过“正常”的人,因为没有人是正常的。每个人看待和体验世界的方式都不同,因为他们看待和做事情的方式不同。还记得那次你的应用出现了一个奇怪的 bug,因为有人以你无法想象的方式使用你的应用吗?我们都有过这样的经历。人们做不可预测的事情正是因为他们的想法和行为不同。对你来说不可思议的动作组合对使用你的应用的人来说可能是完全合理的。相反,对你来说显而易见的事情对一些使用你的应用的人来说却是不可理解的。

当创造任何东西给别人消费时,根据我们自己的经验为人们建造它是完全自然的。这样做的问题是,你或你办公室里的任何其他人都不会成为你正在创造的产品的主要消费者。虽然每个人都是不同的,但在科技公司办公室工作的每个人,很可能在某些关键方面比几乎所有其他人都没什么不同。如果你在科技行业工作,你很有可能非常了解科技,并且可能用过很多科技。也许你甚至喜欢使用它;这不是很多人的经历。

应用科学讲师瓦西里斯·范·格默特警告我们,认为我们是自己的用户是危险的。

在过去的 25 年里,我们主要是为设计[软件]的人设计[软件]。

——瓦西里·凡·盖斯特【8】

你的经历

想想你的朋友和同事,想想你的家人。希望你能和所有这些群体相处融洽,但也有细微的差别。

你的朋友很可能和你相似,因为你选择和他们一起出去玩,因为他们是你的朋友,我已经可以说他们会很棒。也许他们不从事技术工作,但因为你从事技术工作,他们很有可能拥有相当高的数字素养。他们通常和你年龄相仿,来自相似的背景,并且非常喜欢和你做的许多事情。

你的同事可能更加多样化,但是你们仍然会有一些不代表大多数人的共同点。你们都到了工作年龄,能够工作。你们赚的钱都差不多(和一般人群比)。而且你们都将对自己工作的行业有经验和兴趣。与你的家庭相比。我们大多数人都能想到至少有一个家庭成员不使用互联网,也许是一个有残疾的家庭成员,或者对他们来说英语不是他们的第一语言。你的家庭将会比你的朋友甚至你的同事组成一个更加多样化的群体。

考虑这三个群体以及他们的不同之处可能是你从个人经历中得到的最好的例子。但是把所有这些人放在一起思考,你最多只能得到几百个例子,来说明人们的生活是如何支配他们的技术知识的。世界由近 80 亿人口组成。因此,要获得对人们技术体验的代表性调查,你至少需要 1000 个例子。你只选择与你有某种联系的人的抽样方法不会通过审查。

如果我们以自己的能力为基准,我们做出的东西对某些人来说很容易,但对其他人来说却很难。

—微软设计 10

解决这个问题的最好方法是和真实的人交流。我们将在第十一章讨论用户测试。希望您的组织已经在进行某种形式的用户测试了。不要把这当成设计或产品的活动。工程学也能学到很多东西。

Your Network

这里有一个快速练习来强调为什么考虑你认识的人可能不代表你的客户。列出你最信任的五个人。这些人可以是同事、朋友或家人,你可以向他们寻求建议。在继续阅读之前,请这样做。现在把你自己添加到列表中。

现在,列出他们的一些特征。对每个人使用相同的特征。他们多大了?他们的性别是什么?列出他们的种族、性取向、就业状况、宗教和第一语言。记下你意识到的任何残疾。你可能还能想到其他特征的例子。在这里,诚实和保密你的答案是可以的。

看看你对每个问题的回答。我对大多数人的猜测是,这些特征看起来会很接近。没关系。这个练习的目的不是让你羞于扩大你的社交网络,只是想强调你身边的人可能比你想象的更亲近。

People Profiles

帮助整个团队将客户视为个体的一个好方法是创建个人资料。创造一个背景故事。考虑这个人想用你的应用做什么,为什么。想想这个人的环境、经历和能力。最重要的是,给你的人一个名字,用这个名字称呼他们。使用表 2-1 来指导您创建角色。

表 2-1

轮廓截面

| **人名** | 祝你选择名字愉快,但是一旦你创建了个人资料,就必须称呼这个人的名字 | | **年龄** | 给出一个大概的年龄范围 | | **性别** | 请记住,大约有 2%的美国人不认为自己是男是女 11 | | **直系亲属** | 他们有需要照顾的孩子或成人吗?他们结婚了吗,和家人住在一起,还是独自生活? | | **工作和收入** | 你的人可能是在职的,失业的,个体经营的,未充分就业的,或者在事业上非常成功的。也许他们是彩票中奖者 | | **残疾** | 全球约有 14%的人患有残疾。你应该把目标放在一系列反映不同残疾的档案上,而不是一个都没有 | | **背景故事** | 狂野一点。或者不是。请记住,此简介旨在代表一个真实的人,但请随意在此寻找乐趣 | | **这个人为什么要用你的 app?** | 你的应用能为他们做什么?这是一种选择,还是他们因为某种原因不得不用你的 app? |

神入

软件不是由冰冷的、不经思考的算法组成的。有时,这被用来为以软件的名义做出的错误决策进行无力的辩护。更重要的是,这降低了你作为开发人员的技能。它隐藏了这样一个事实,即创建软件是一门手艺,我们这些制作软件的人是真正意义上的手艺人。我们手工构建漂亮的软件,真正关心的是软件的内容和最终结果。我们总是在磨砺我们的技能,拓展我们的个人工具箱。

我想提出的是,一个软件工匠可以拥有的最伟大,也是最容易被忽视的工具之一是同理心——理解许多其他人,不像你,会直接受到你在创建应用时所做决定的影响的能力。这必须是数字包容的核心原则。同理心不是一项技能,你可以通过对一个项目有最多的承诺或在 GitHub 上有最多的明星来学习。这是一个工具,你只能通过对人和你的手艺产生真正的兴趣来提高。

很多书会告诉你成为一名伟大的工程师所需要的必备技能;这不是本书的预期目的。我发现了一个清单,我觉得这是成为一个真正的软件工匠所必需的技能:

  • 对感情和美学的开放

  • 与人打交道

  • 合作的

  • 工作生活平衡 13

然而,这个列表的作者从来没有打算把它们作为成为一个更好的工程师的指南。相反,恰恰相反。这些都是谷歌前雇员詹姆斯·达莫尔在他臭名昭著的“谷歌备忘录”中给出的例子。这份名单意在批评女性软件工程师。性别主题的基本读物 14 会告诉你这些例子是基于过时的、不可信的研究。

相反,对于任何从事软件工作的人来说,它们都是一套非常理想的技能。通过确保我们的团队拥有尽可能丰富的生活经验,我们可以利用这些经验来帮助我们做出明智的决策。如果你有一个男性团队,你就排除了 50%的人的经历。

我提到达莫尔是因为他关于多样性的错误主张在许多方面与本书背道而驰。在题为“弱化共情”的一节中,达莫尔指出,共情导致我们“偏爱与我们相似的人,并怀有其他非理性和危险的偏见。”我想让你从这本书里学到的恰恰与达莫尔所说的相反。我们应该强调同理心,因为它有助于我们认识和克服我们潜意识中对与我们相似的人的偏见。只有带着情感和对什么是对的深刻的个人理解,才有可能做到感同身受。随着同理心带给我们的经验范围的扩大,我们可以不带感情地去战胜这些挑战。

移情作为一种动力

所以,你很有同情心。你想有所作为。你想为残疾人解决问题。这是一个崇高的目标,但它是在帮助残疾人,还是让你感觉更好?当你说你想为残疾人修理东西时,想想你在暗示什么。残疾没有错,也不需要固定。

有很多恐怖的故事,软件以可访问性和残疾用户的名义变得更糟,而这些人应该心存感激。 15 注意不要把感同身受当成行动的理由,而是调查的理由。同理心不是真实经历的替代品;某人的生活经历应该比任何感觉或指导方针更能引导你。交互设计师 Marie Van Driessche 给出了以下建议:

请残疾人士与你同桌。大多数人对与残疾人交谈不感兴趣,他们更喜欢感同身受。但是同理心并没有帮助我们。

-玛丽·范·德里斯钦斯基第十六第三

残障人士希望有同等的体验。他们希望能够像其他人一样使用你的应用。易接近性不是一种让你感觉更好或获得你的品牌影响力的姿态。可访问性是实现软件包容性的工具。

偏见

我们都有无意识的偏见。我们已经进化成为一种生存机制,这是人类完全自然的一部分。因此,对抗无意识偏见可能会适得其反。对无意识偏见训练的研究表明,如果有的话,这使偏见更糟,并鼓励刻板印象。 17

最好的选择是承认并接受我们都有偏见,并利用它们来帮助指导你。确保你的团队尽可能多样化。这将有助于你的团队通过利用彼此的个人知识和经验,以你自己的偏见的形式,与尽可能多的人产生共鸣。通过这种方式,您可以建立一个更广泛的基础来检查在您的软件中做出的决策的后果。

快速移动并打破东西

总的来说,我希望我们最终能够摒弃导致软件行业大量不良事件的哲学——“快速行动,打破常规。”就连马克·扎克伯格 18 自己现在似乎也意识到这不是一种合法的经营方式,更不用说是一种以消费者为中心的业务了。我想提出一种新的理念,我们可以用它来制作软件,在这种理念下,我们以一种深思熟虑和感同身受的方式工作,来逐步改善尽可能多的人的体验。

摘要

  • 包容性思维植根于工业设计和建筑。但这并不意味着它的指导原则不适用于工程。

  • 可访问性是关于包容性。做出改变,将你的客户带入你的应用,而不是为不同能力的人创造不同的体验。允许您的客户定制适合他们的体验。

  • 记住你的用户是谁;他们不会永远像你、你的同事、朋友或家人一样。用户测试是了解人们如何体验你的应用的重要工具。确保你的参与者是多样化的。

  • 同理心是任何一个软件工程师的必备素质。这有助于你记住将你的用户视为独特的个体。

我们现在有了一个关于可访问性和包容性意味着什么以及是什么驱动了这些领域的思考的背景。让我们开始看看我们可以帮助不同的人使用我们的应用的实际方法。在讨论任何具体技术之前,我们应该看看我们的目标是什么。网页内容可访问性指南,或 WCAG,形成了一个明确的框架,说明我们应该对我们的应用进行哪些改进,以使它们更容易访问。

Footnotes 1

https://projects.ncsu.edu/ncsu/design/cud/about_ud/udprinciplestext.htm

  2

“W3C 网页内容可访问性指南(WCAG) 2.1”,W3C,2019 年 10 月 5 日获取。https://www.w3.org/TR/WCAG21/

  3

www.paciellogroup.com

  4

“包容性设计原则”,包容性设计原则,2019 年 10 月 5 日访问。 https://inclusivedesignprinciples.org

  5

访问 www.microsoft.com/design/inclusive/ 了解更多关于他们包容性设计计划的信息。

  6

包容性强,微软设计,2016。 https://download.microsoft.com/download/b/0/d/b0d4bf87-09ce-4417-8f28-d60703d672ed/inclusive_toolkit_manual_final.pdf

  7

“包容性”,微软设计,引用来自美国人口普查局,肢体生命基金会,截肢者联盟,CDC.gov MedicineHealth.com,UCSF 残疾统计中心的研究。

  8

凡·格默特,瓦西里斯。《独家设计》,独家设计,2019 年 10 月 8 日访问。 https://exclusive-design.vasilis.nl/

  9

“当前世界人口”,Worldometer,2019 年 10 月 13 日获取。 http://www.worldometers.info/world-population/

  10

“包容”,微软设计。

  11

威廉·卡明斯。“当被问及性别时,一些人会选择‘X’”,《今日美国》,2017 年 6 月 27 日。 https://eu.usatoday.com/story/news/2017/06/21/third-gender-option-non-binary/359260001/

  12

“增进残疾人健康:信息图”,世界卫生组织,2019 年 10 月 12 日获取。 www.who.int/disabilities/infographic/en/

  13

凯特·孔格,“独家报道:这是谷歌内部流传的整整 10 页的反多样性文章[更新]”。2017 年 5 月 8 日。https://gizmodo.com/exclusive-heres-the-full-10-page-anti-diversity-screed-1797564320

  14

吉娜·里彭的《性别化的大脑》是一个很好的起点。

  15

梅马特。《没有同理心的设计》,2019 年 11 月 23 日。 https://accessibility.scot/design-without-empathy/

  16

范·德瑞斯彻,玛丽。推特帖子。2019 年 9 月 4 日下午 2 点 33 分。 https://twitter.com/marievandries/status/1169242121108369409

  17

米歇尔·m·杜吉德,托马斯·亨特,梅利莎·c .〈宽容刻板印象?对陈规定型观念普遍存在的认识如何影响陈规定型观念的表达”。应用心理学杂志,100(2),343–359 页。2015.https://doi.org/10.1037/a0037908

  18

斯塔特尼克。“扎克伯格:‘快速行动,打破常规’不再是脸书的经营方式”,CNET,2014 年 4 月 30 日。 www.cnet.com/news/zuckerberg-move-fast-and-break-things-isnt-how-we-operate-anymore/

 

三、移动网络内容可访问性指南

有了网站内容可访问性指导方针这样的名字,人们很容易把它们写成不适用于移动设备。然而,这个名字是在整个 20 世纪 90 年代和 21 世纪初指导方针制定的时代的功能,最后一次重大更新是在 2008 年,当时手机还没有像今天这样普及。这与该倡议来自万维网联盟的事实相结合。这个名字也有点拗口,所以我们将坚持使用 WCAG 的常见缩写。

WCAG 1 就像任何一套指导方针一样,遵守 WCAG 教就像是一个复选框练习。可访问性实际上就是人们如何体验你的应用。但是除非你有足够的资源对大量不同辅助技术的用户进行广泛的测试,否则 WCAG 指南是目前为止你能得到的最好的指南。

W3C 将 WCAG 分成了四层。它们从四个首要原则开始——可感知、可操作、可理解和可靠。这些原则各有准则,接着是成功标准技巧。推荐最初是明确为网络而写的。但是大多数的原则指导方针都是通用的,确实可以转化为移动设备,即使它们的成功标准技术并不总是符合。最新版本 WCAG 2.1 于 2018 年获得批准,并涵盖了更多与移动相关的问题,如屏幕方向。

WCAG 自 2012 年起成为 ISO 标准,是全球许多无障碍法律的基础。它通常被用作法院决定数字体验是否可访问的基准,或者用于可访问性诉讼。因此,就法律而言,WCAG 非常适用于手机。

在这一章中,我不会完整地介绍每个指南;为此,我建议您亲自阅读当前的 WCAG 2.1 规范,可在 www.w3.org/TR/WCAG21 获得。相反,我将提供一些一般性的建议,告诉你如何在手机上遵守每一条准则,以及你可以使用什么工具来做到这一点。我们将在本书的后面详细介绍这些技术和工具。简而言之,我试图将专注于网络的成功标准技术转化为移动环境。W3C 对 Web 的详细指导比这本书的页数要多得多,所以为了简洁起见,我将保持高水平。W3Cs Web Accessibility Initiative 指导如何将 WCAG 应用于手机 2 在很大程度上,当 WCAG 指南提到“网页”时,我们可以假设这包括移动应用内容。

可知觉的

信息和用户界面组件必须以用户可以理解的方式呈现给用户。

—WCAG 2.1

第一个原则是可感知的,包括应用中的内容以及向客户提供这些内容的方式。用一句话来总结这个原则,我会用“替代方案”

回想一下我们在第一章对电话的讨论;按照最初的设计,电话只使用一种媒介,即音频。虽然这将涵盖大多数用例,但它立即排除了说话困难的人和听力困难的人。TDD 的发明是一个必要的选择,让处于这种情况下的人拥有和我们其他人一样的体验。同样,如果您提供的内容是纯视觉格式,如图像、屏幕阅读器不可用的文本或没有音频轨道的带字幕的视频,那么有视觉障碍的客户将无法访问这些内容。

替代文本

为任何非文本内容提供文本替代,以便将其转换为人们需要的其他形式,如大号字体、盲文、语音、符号或更简单的语言。

—WCAG 2.1

确保所有非文本内容都有适当的等效文本替代。这通常适用于有意义的图像。内容和非内容之间的区别在这里是至关重要的。为装饰图像提供可访问的描述性标签可以为用户提供更丰富的体验。但是注意不要分散你应用内容的注意力。

这两个平台都内置了向几乎任何对象添加文本替换的功能。我们在 iOS 可访问性模型和 Android 可访问性模型章节中详细介绍了每个选项。Android 使用contentDescription属性(列表 3-1 和列表 3-2 )。在 iOS 中,accessibilityLabel也会达到同样的效果(清单 3-3 )。这些方法中的每一种都有实现细节;详见第四章和第六章。

submitButton.accessibilityLabel = "Submit"

Listing 3-3Setting an accessibility label in iOS

submitButton.contentDescription = "Submit"

Listing 3-2Setting an Android contentDescription in code

<Button
    ...
    android:contentDescription="Submit" />

Listing 3-1Setting an Android contentDescription in a layout XML file

Alternative Text For Images

具有 UI 功能的图像(如按钮)必须有一个清晰的描述性文本替换标签,以便屏幕阅读器用户可以知道有一个可用的操作以及该操作的后果。

装饰图像需要更多的考虑。小的装饰性图像,比如吸引人们注意表格行中内容的图标,可能不应该包含替换文本。这增加了不必要的噪音,增加了导航所需的滑动次数,混淆了用户界面的顺序,导致用户失去上下文。

然而,更大的装饰性图像,如英雄图像,可能应该包含图像用途的文本描述,例如,一个勾形图标应该包含“你已经准备好了”的描述,而不是“勾形图标”这个标签不应该将焦点从页眉上移开,而是为那些试图在屏幕上定位自己的视力不佳的屏幕阅读器用户提供一个指示。如果屏幕阅读器跳过了屏幕的大部分区域,这些用户可能会认为屏幕的这一部分包含您没有完全设置为可访问的内容,并会尝试查找该区域中的任何内容。这将导致在 iOS 上一个恼人的“扣篮”声,如果你不能描述什么存在的话。可以把这想象成屏幕阅读器相当于“这一页故意留白”

基于时间的媒体

为基于时间的媒体提供替代品。

—WCAG 2.1

对你我来说,这意味着音频和视频。此外,它还包括任何具有时间成分的媒体,如动画。视频和音频应该有字幕或转录。优选地,视频应该包括音频描述,并且理想地,音频和视频都应该包括或具有手语选项。在第五章和第十章中可以找到更多关于媒体字幕和备选曲目的详细信息。

本指南不包括您作为文本替代物提供的视频或音频。如果您确实提供了这些选项,请务必标记出来。如果你不能让你的用户明白你的媒体是一种选择,那些不能使用它的人可能会感到被排斥。

适合的

创建能够以不同方式呈现的内容(例如更简单的布局),而不会丢失信息或结构。

—WCAG 2.1

适应性指南远离了内容,涵盖了如何在 UI 中呈现内容。

以清晰、有意义的顺序呈现内容。您可以通过良好的界面设计来实现这一点,但是在测试时要注意启用屏幕阅读器。对于视力正常的用户来说,它们经常以不自然的方式在屏幕上导航。例如,考虑一个带有大的英雄图像和标题的屏幕。你的眼睛通常会浏览图片并被标题吸引。除非您指定标题应该是最初聚焦的项目,否则屏幕阅读器将首先聚焦于图像的 alt 文本。

以多种感官特征呈现信息。例如,不要只依赖颜色,而是要结合颜色、形状、大小、位置或声音等属性。你可以使用任何或所有这些模式来推断意义。

输入字段和其他控件应该标识该控件的目的或动作。使用我们之前讨论过的 Android 上的contentDescription属性和 iOS 上的accessibilityLabel属性来实现这一点。在 iOS 上,可访问性特征是告知辅助技术及其用户控件如何工作的强大工具。如果需要,iOS 上的accessibilityHint(列表 3-5 )或 Android 上的hint(列表 3-4 )可以给出额外的上下文。关于 Android 可访问性模型的第四章和关于 iOS 可访问性模型的第六章提供了关于如何使用它们的更多细节。

sendButton.accessibilityHint = "Sends your message."

Listing 3-5Setting an accessibility hint in UIKit

<EditText
...
android:hint="Email Address" />

Listing 3-4Setting a hint in an Android layout XML file

Providing Hints

当使用描述、标签或提示来提供上下文时,很容易给出过多的背景,例如,在文本字段上添加“双击以编辑”作为提示。

记住:屏幕阅读器用户在使用屏幕阅读器界面时会像你或我在使用可视界面时一样自然。虽然导航中的这些差异对您来说可能是新的,但没有必要解释它们。这样做增加了不必要的噪音,而且可能会让你的用户觉得你高人一等。

WCAG 2.1 的一个新的补充是手机日益流行的结果。用户界面不应局限于一个方向,而应允许旋转到任何设备支持的方向。这适用于除非明确的方向是一个明确的目的的要求,如音乐键盘需要景观。

可区别的

让用户更容易看到和听到内容,包括将前景与背景分开。

—WCAG 2.1

可区分指南涵盖了用户如何区分应用中的元素。该指南包括对比度、文本大小和行距、背景音频等基本规则。一些残疾,如色盲,可能会妨碍我们区分元素的能力。因此,坚持这些指南并在需要的地方允许定制是非常必要的。除非你的布局需要,否则避免二维滚动,因为这可能会触发对运动敏感的人。启用一些辅助技术进行控制可能会很有挑战性。

本指南还就以下要素提供了建议。

颜色

你在任何应用中使用颜色都是至关重要的。调色板的正确选择是让你的应用与众不同的重要因素。使用得当的颜色可以微妙地暗示意义,有助于理解。然而,请记住,不是每个人对颜色的体验都是一样的;因此,颜色不应该是识别元素或传达意义的唯一方式。将颜色与文本、形状或动画结合起来。例如,黄色警告三角形不仅仅被称为“黄色警告”——三角形部分对其效用至关重要。

文本颜色和背景颜色之间的对比度是一个重要的考虑因素。大文本(定义为最小 18 磅或 14 磅粗体)的最小对比度应为 3:1。较小的文本的对比度应为 4.5:1。理想情况下,文本的对比度应该是 7:1,较大的文本应该是 4.5:1。我们将在第十一章介绍如何检查色彩对比度。

有些人,如患有阅读障碍、Irlen 综合症或色盲的人,可以从自定义背景颜色的功能中受益。如果你想让你的应用的可访问性更上一层楼,这将是一个很好的补充。

声音的

应用中任何持续时间超过 3 秒的音频,包括视频中的音频,都应该有控件。这些应该允许暂停、停止和调节音量。音量控制应该独立于系统控制,以便让您的客户保持他们选择的系统级别。

任何语音音频都应该避免背景声音。或者,允许禁用背景声音,或者让背景声音比语音声音至少安静 20db(至少四倍)。背景噪音会影响注意力障碍的人;对于一些有听力障碍的人来说,如果他们的听力失真,这还会使前景音频难以确定。

文本

文本的大小应该是字形大小的两倍,而不会丢失内容或功能。确保您支持系统,两个平台上的动态文本大小将满足这一要求。避免使用文本图像,因为它们不支持屏幕阅读器或文本大小调整。如果必须使用包含文本的图像,请确保在图像中添加包含文本的屏幕阅读器可访问的标签。使用 Android 上的contentDescription属性或 iOS 上的accessibilityLabel属性来完成此操作。

设置文本格式时,要做到以下几点:避免完全对齐,文本行数最多 80 个字符,段落间距为行距的 1.5 倍。通过提供更改文本和背景颜色的机制,让您的用户根据自己的需求进行定制。

可操作的

用户界面组件和导航必须是可操作的。

—WCAG 2.1

正如这个原则的名字所暗示的,operable 涵盖了你的应用是如何工作的。这包括使用客户可能选择用作替代输入或输出机制的任何辅助技术。

键盘可访问

从键盘上使用所有功能。

—WCAG 2.1

确保您的应用可以使用外部键盘导航。确保你的应用没有键盘陷阱——一个可以通过键盘聚焦但只会通过其他方式失去焦点的控件。当使用屏幕阅读器导航界面时,同样的情况也会发生。测试应用时,请确保浏览到启用了屏幕阅读器和外部键盘的每个控件。

两个平台都支持键盘导航,但是每个平台的实现都有不同的不足。参见第五章和第十二章了解更多信息。

期限

为用户提供足够的时间阅读和使用内容。

—WCAG 2.1

出于许多原因,时间限制可能是可取的:释放产品或资源以防止拒绝服务攻击,或者通过限制授权令牌的未授权使用来增加用户的安全性。然而,时间限制会给一些人造成障碍。使用辅助技术导航应用可能非常耗时,尤其是在可访问性设计不符合标准的情况下。此外,患有焦虑症的人会发现时间限制非常有压力。

如果没有严格的时间要求,尽可能避免时间限制。如果您确实包含了时间限制,请考虑为您的用户提供一种选择限制或延长限制的机制。在限制即将到期之前发出警告,并提供重置或延长的选项。如果需要重新进行身份认证,请允许您的客户在其身份认证过期之前从他们停止的地方继续。

此外,本指南还提供了移动、闪烁滚动或自动更新内容的规则。应用户要求,提供暂停、停止或隐藏这些功能的机制。

癫痫发作和身体反应

不要以已知会引起痉挛或身体反应的方式设计内容。

—WCAG 2.1

任何闪光或闪烁不应该超过每秒三次。众所周知,这会引起癫痫患者的身体反应。此外,您应该为客户提供禁用动画的选项,除非这对您的应用的功能至关重要。在 iOS 上,要听isReduceMotionEnabled属性。

可操纵的

提供帮助用户导航、查找内容和确定位置的方法。

—WCAG 2.1

这里假设你是一个视力正常的用户,当你看到一页内容时,你的眼睛和大脑会下意识地一起工作,为你建立一个可用的心智模型。这种无意识的技术让你可以在内容之间瞬间跳转,找到现在对你最重要的内容。出于这个原因,数字广告试图尽可能分散注意力。如果广告没有分散注意力,你的大脑可能会判断它不重要,甚至在你没有意识到的情况下跳过。如果你没有完全看到,这是一个工具,你不能从中受益。你将依靠额外的线索来充实自己的内容。

确保屏幕阅读器和其他辅助技术能够以逻辑顺序导航你的应用是至关重要的,确保内容与有意义的标题分开。有时,屏幕阅读器的导航顺序可能与您的眼睛自然看到的顺序不同。有可能以多种方式实现正确的、语义的屏幕阅读器顺序。为屏幕阅读器设置一些隐藏的元素,调整内容顺序或屏幕阅读器的主要焦点,或者使用语义视图都是实现这一点的技术。我们将在本书的后面部分讨论这两个问题。

每个屏幕都应该有一个屏幕阅读器可以访问的标题,并且你应该这样标记任何内容标题。这允许屏幕阅读器用户跳过有意义的标题,类似于我们上面讨论的略读。

你应该努力让所有的按钮都有独特的、有意义的文本标签,这些标签不需要任何额外的上下文就可以使用。

输入模式

使用户更容易通过键盘以外的各种输入来操作功能。

—WCAG 2.1

如果你的应用利用设备的内置加速度计来确定你的应用的运动和控制功能,为那些可能难以控制精细运动的人提供一个替代选择。

点击目标应至少为 44 像素见方。Android 的指南推荐最小 48px 的正方形。任何更小的尺寸都难以准确按压,并且会导致意外输入和客户失望。

该指南还涵盖了可用于控制应用功能的触摸手势。考虑到不可能所有用户都准确地执行您指定的手势,所以提供替代方案。iOS 允许您将元素(不限于按钮)标记为具有辅助功能操作。这些可以由用户使用他们的辅助技术直接触发。

可理解的

信息和用户界面的操作必须是可理解的。

—WCAG 2.1

WCAG 的第三个原则——可以理解——旨在提高你的应用及其功能的清晰度。这个原则涵盖了应用的内容、设计和行为。

易读的

使文本内容具有可读性和可理解性。

—WCAG 2.1

尽可能避免在你的文章中使用习语、行话和缩写。对于任何你使用的,提供一个机制给你的用户来决定他们的定义。理想情况下,目标是任何书面内容都可以在初中教育水平上理解。 3

可预言的

让网页以可预测的方式显示和操作。

—WCAG 2.1

设计和操作的一致性对于本指南至关重要。没有两个外观相同的控件应该有不同的功能。反之亦然;两个功能相同的控件应该具有相同的外观。

上下文的任何变化——移动或改变控件或内容的含义或行为,如导航到新屏幕——都不应在没有警告的情况下发生。这些应该只在用户请求时发生,比如说,通过按下一个按钮。或者你应该通知你的客户将会发生一些事情,也许是关于一个装载旋转器。对于一些有心理健康问题或学习困难的客户来说,未能让用户为环境的变化做好准备会导致焦虑。此外,视障用户可能没有意识到上下文已经改变,从而使得新内容的含义不清楚。

输入辅助

帮助用户避免和纠正错误。

—WCAG 2.1

当通过表格从客户那里收集数据时,任何错误都应该清楚地突出显示。提供导致错误的原因以及如何纠正错误的指示。每个字段都应该向用户提供关于其用途的清晰说明。

理想情况下,任何表单都应至少提供以下特征之一:

  • 可逆的

    可以逆转数据的提交。

  • 检查

    输入的数据在提交前经过验证。您的客户有机会纠正任何错误。

  • 确认的

    在最终完成提交之前,让您的客户有机会检查、确认和更正输入的任何数据。

粗野的

内容必须足够强大,能够被...辅助技术。

—WCAG 2.1

最后一条原则只包含一条指导方针。基本原则是,你的应用应该与用户选择的平台上的任何辅助技术兼容。

兼容的

最大限度地兼容当前和未来...辅助技术。

—WCAG 2.1

控件的用途应该由用户选择的辅助技术来决定。您可以使用 iOS 上的可访问性特征来实现这一点。例如,任何充当按钮的控件都应该标记为按钮。这允许所使用的辅助技术决定如何处理该元素。

摘要

  • 万维网联盟的网页内容可访问性指南规定了衡量应用可访问性的规则。

  • 这是一个国际标准,并形成了决定您的应用是否可访问的法律框架。如果你不符合 WCAG 的标准,你就有法律纠纷的风险。如果你担心,找一个 WCAG 专家来检查你的应用,并确定哪些准则适用于你以及如何适用。

  • WCAG 是来自用户和专家的资源丰富的研究的结果,这些人真的知道什么对可访问性最好。用他们丰富的经验来指导你。

  • 你的应用应该是可感知的,可操作的,可理解的,健壮的。

我们已经介绍了应该考虑哪些因素来提高应用的可访问性,并简要介绍了为什么应该考虑这些因素。现在让我们来看看每个平台为您提供的符合这些准则的工具。首先,我们从 Android 开始。

Footnotes 1

https://www.w3.org/TR/WCAG21/

  2

www.w3.org/WAI/standards-guidelines/mobile/

  3

有关定制语言的指导,请参见美国英语的 www.plainlanguage.gov/guidelines/ 和英国英语的 www.plainenglish.co.uk/free-guides.html

 

四、Android 可访问性模型

与平台的其他部分一样,Android 可访问性是高度可定制的。可访问性的很大一部分是关于可定制性的,所以 Android 在这方面有巨大的优势。如果 Android 没有一个适合特定需求的系统设置,那么任何开发者都可以创建一个定制的可访问性服务来满足这个需求。我们将在后面的“查看可访问性树”活动中粗略地看一下这个。由于手机和可用软件版本的差异很大,为了避免疑问,我使用的是运行 Android 10 的谷歌 Pixel 设备。

Google 的设计系统 Material Design 1 贯穿于 Android 系统 app 中,是你创建 app 的基础。谷歌开发材质设计时考虑了高标准的可访问性,并遵循用户界面设计的最佳实践。使用 Android 的内置控件(图 4-1 ) 2 )并遵循材质设计原则将意味着你的应用是一致的——不仅与 Android 系统一致,还与你的应用的其他部分一致。 3 这将帮助您的所有用户在使用您的应用时有宾至如归的感觉,并帮助您保持高水平的可访问性。

img/486920_1_En_4_Fig1_HTML.jpg

图 4-1

material.io 中的材质设计组件

Material design 的指南很好地介绍了如何使用 Android 的工具来创造无障碍体验。通读谷歌关于材质设计原则 4 和材质设计可及性 5 的介绍,以获得最佳实践。材质设计指南中的大多数信息都与制作 Android 应用的任何人相关,而不仅仅是设计师。

可访问性树

在我们介绍 Android 上可用的可访问性特性之前,让我们先了解一下 Android 可访问性模型是如何为辅助技术服务的。当使用 Android 应用时,您将熟悉 Android 从 XML 中扩展出来的控件和视图。创建一个你可以与之互动的用户界面。但是如何将这些视觉元素转换成辅助技术可以使用的格式呢?

Android 创建了一个被称为可访问性树的东西,它是呈现在屏幕上的元素的分层表示。辅助服务可以使用此辅助功能树来确定如何显示信息。Android 对你的用户界面以及如何向辅助技术表示做出了一些合理的假设。大多数情况下,这将提供一个可访问的功能体验。有时你可能需要调整这个树来呈现一个更好的体验。本章将为你提供实现这一目标的工具和技术。

辅助功能节点

Android 以可访问性节点树的形式向可访问性服务提供数据。辅助功能节点是屏幕上元素的表示。它们包含关于辅助技术可以执行的元素和操作的内容和元数据。

辅助功能节点和屏幕元素之间的区别是至关重要的。Android 并没有通过屏幕元素来呈现辅助技术,而是一个代理对象,包含与可访问性相关的信息。一旦可访问性服务接收到一个节点,这个节点就是不可变的。对视图的更改不会透露给可访问性服务,直到该服务下次请求该节点。

“辅助功能”节点包含对辅助技术有用的元素信息,例如,文本和描述等属性,以及元素是否可滚动或是否还包含标题等信息。元素在屏幕上的位置及其层次结构的细节也是如此。

Viewing The Accessibility Tree

Android 允许任何开发者创建可访问性服务。该服务可用于在屏幕上呈现内容、控制屏幕或设备,或者您可能期望辅助技术执行的任何其他任务。我们不会在这本书里讨论创建这样一个服务的来龙去脉,尽管 Android 确实提供了一个指南。我们将触及一些基础知识来说明可及性树是如何工作的。

如果你还没有,克隆这本书的 GitHub repo。导航至文件夹练习 4-1。在 Android Studio 中打开这个示例代码,然后单击 Run。

在您的设备或模拟器上,打开“设置”并找到“辅助功能”。在顶部,您应该会看到新的辅助功能服务列在下载的服务下面(图 4-2 )。打开服务,并启用它。

img/486920_1_En_4_Fig2_HTML.jpg

图 4-2

我们设备辅助功能设置中的新辅助功能服务

辅助功能服务将在屏幕顶部覆盖一个“获取辅助功能树”按钮(图 4-3 )。

img/486920_1_En_4_Fig3_HTML.jpg

图 4-3

“获取可访问性树”按钮覆盖在我们屏幕的顶部

在 Android Studio 中打开 Logcat 标签。单击新的“获取可访问性树”按钮。您将看到打印的一组输出(图 4-4 )。这些是屏幕上所有当前元素的文本描述和标签。尝试导航到不同的屏幕,并再次点按该按钮,以查看以不同布局呈现给辅助功能服务的内容。

img/486920_1_En_4_Fig4_HTML.jpg

图 4-4

Android 应用启动器的可访问性树输出

有关可访问性服务可用属性的完整列表,请查看 Android 文档。 7 考虑查询不同的值(清单 4-1 )比如isHeading,看看每个屏幕如何报告自己的可访问性。例如,请参见下面的清单。

if (node.isClickable) {
    Log.d("NODE", "is Clickable")
}

Listing 4-1Printing to the console if an element is clickable

辅助功能 API

Android 的可访问性 API 负责管理呈现给可访问性服务的视图。Google 在创建他们的标准控件时做了一些合理的假设。坚持使用 Android 类的控件,你的可访问性就没问题了。但是有时候你需要做一些调整来改善我们呈现给可访问性用户的内容。当您创建自己的自定义控件时尤其如此。如果你改变了 Android 的内置控件,你必须确认你没有删除任何辅助功能。我们将看看您可能需要考虑在这里设置的一些属性。

内容描述

对于像 TalkBack 这样的向用户呈现元素的辅助技术,该技术需要文本表示来呈现。默认情况下,contentDescription被设置为视图的文本值。对于没有文本值的元素,或者辅助技术提供的文本值不起作用的元素,您应该设置contentDescription值(列表 4-2 和列表 4-3 )。

contentDescription应该是一个简洁的、描述性的标签。通常一个词就足够了,比如“提交”不要包含诸如“按钮”这样的控件类型,因为 Android 会为您添加。不要重复描述,保留这些独特的辅助导航。

submitButton.contentDescription = "Submit"

Listing 4-3Setting a contentDescription in code

<Button
    ...
    android:contentDescription="Submit" />

Listing 4-2Setting a contentDescription in a layout XML file

与所有可以在布局文件中设置的属性一样,该值也可以在设计模式下在属性窗格中设置,如图 4-5 所示。

img/486920_1_En_4_Fig5_HTML.jpg

图 4-5

在“属性”窗格中更改属性

对于可访问性很重要

如果一个元素纯粹是装饰性的,比如一个伴随文本的图标,那么将这个元素添加到你的可访问性树中意味着对对讲用户的额外的不必要的点击。在这种情况下,我们不应该向辅助技术提供这种元素。你可以通过设置importantForAccessibilityno(列表 4-4 和列表 4-5 )来实现。或者,如果通常隐藏的元素提供上下文,您可以将该值设置为 yes。

textIcon.importantForAccessibility =
      IMPORTANT_FOR_ACCESSIBILITY_NO

Listing 4-5Setting a view inaccessible in code

<TextView
     ...
     android:importantForAccessibility="no" />

Listing 4-4Setting a view inaccessible in XML

暗示

提示值是元素的文本表示,独立于元素的文本值(清单 4-6 )。Android 以不同的方式使用这些值,这取决于您的元素是否有另一个文本值。

对于没有文本值的元素,提示显示为占位符值。提示也被 TalkBack 作为文本标签读取。这对于EditText元素向用户提供应该输入什么信息的提示很有用。出于这些目的,您的提示应该简短且具有描述性,遵循与上面的contentDescription相同的队列。

对于具有文本值的元素,不显示提示。TalkBack 读取元素文本值或contentDescription和元素类型后的提示。如果提示有助于用户浏览您的 UI,您可以使用它来为用户提供更多的上下文。例如,一个理想的用途是对按下按钮的后果进行简短描述。带有文本“发送”的按钮可能有“发送您的消息”的提示这使得将要执行的操作和预期的结果变得很清楚。作为编写提示的一般指南,想象一下向一个朋友解释这个控件是做什么的。

<EditText
    ...
    android:hint="Email Address" />

Listing 4-6Setting a hint in a layout XML file

可访问性标题

当使用 TalkBack 导航屏幕时,没有视力或视力很差的用户通过在屏幕上从左向右滑动来导航。TalkBack 从左上到右下依次关注屏幕上的每个元素。对于有大量内容的屏幕,这意味着你的客户需要浏览大量不相关的内容才能找到他们想要的信息。这样标记你的标题(列表 4-7 和列表 4-8 )允许对讲用户跳过内容浏览标题。

headingLabel.isAccessibilityHeading = true

Listing 4-8Setting an element as a heading in code

<TextView
        ...
        android:accessibilityHeading="true" />

Listing 4-7Setting an element as a heading in a layout XML file

最小尺寸

所有交互式元素,如按钮、复选框、开关和其他控件,必须至少为 44 个相对像素的正方形,以符合 WCAG 指南。Android 建议使用最少 48 个相对像素。

Android 提供了一种简单的方法来确保始终如此。无论设备或用户界面的其他部分如何,都将保持这种状态。针对任何交互控件设置minWidthminHeight值(列表 4-9 和列表 4-10 )。养成习惯,让它成为你添加到 UI 中的任何控件的标准属性。

imageButton.minWidth = 48
imageButton.minHeight = 48

Listing 4-10Setting a minimum size for an image button in Kotlin

<ImageButton
      ...
      android:minHeight="48dp"
      android:minWidth="48dp" />

Listing 4-9Setting a minimum size for an image button in XML

的标签

假设我们向客户展示一个表单,其中有一些EditText字段供他们填写。我们的客户如何知道在哪个字段输入什么数据?一种常见的方法是给我们的EditText添加一个提示值。Android 将此显示为该字段的占位符(图 4-6 )。

img/486920_1_En_4_Fig6_HTML.jpg

图 4-6

编辑带提示的文本控件(左)和带内容的同一控件(右)。注意内容提示是隐藏的

当该字段是空的时,这很好地工作。一旦该字段输入了值,该占位符就消失了(图 4-6 ),并且不再清楚该字段的用途。对于注意力或记忆力有问题的人来说,这是一次糟糕的经历。labelFor允许我们将一个TextView元素绑定到一个EditText或其他控件上。无论控件处于何种状态,该标签都保持可见(图 4-7 )。不幸的是,这种技术确实给对讲用户增加了额外的不必要的刷卡,但总的来说,我相信使用labelFor属性会给你的客户带来更多的好处,而不是带来不便。

img/486920_1_En_4_Fig7_HTML.jpg

图 4-7

带有关联标签的 EditText 控件(左)。即使输入了内容,标签仍然可见(右图)

在作为参数提供的控件的“标签”的TextView上设置了labelFor属性(清单 4-11 和清单 4-12 )。提供您想要将此标签绑定到的视图的id

textView.labelFor = editText.id

Listing 4-12Setting a label for an EditText control in Kotlin

<LinearLayout
      ...
      >

      <TextView
           ...
           android:layout_marginBottom="0dp"
           android:labelFor="@+id/editText"
           android:text="@string/name" />

      <EditText
           ...
           android:id="@+id/editText"
           android:layout_marginTop="0dp"
           android:text="" />

</LinearLayout>

Listing 4-11Setting a text label for an edit text control in XML

遍历顺序

可访问性树是按照自然阅读顺序构建的。这意味着对讲和其他辅助技术将从最左上角的项目移动到最右下角的项目。这通常是正确的行为。但是有些设计,比如交错排列的元素,可能与视觉用户的阅读方式不同。这种布局的一个例子可以在谷歌 Play 商店看到,一个应用的下载量直接垂直显示在“下载”的标题下

在这种情况下,我们可能希望通过告诉 Android 当一个可访问性服务导航我们的 UI 时,哪个元素应该出现在下一个或上一个来改进我们的可访问性树。Android 有两种不同的方式来指定遍历顺序,这取决于客户使用的技术类型。如果您发现 Android 为您确定的遍历顺序不理想,那么我们需要确保我们设置了这两个选项。

可访问性遍历顺序

我们可以使用accessibilityTraversalAfteraccessibilityTraversalBefore属性来做到这一点。就我个人而言,我发现从它们的名字中理解这些属性的行为很有挑战性。设置该属性的元素是“之前”和“之后”所指的元素。让我们在图 4-8 中对此进行说明,以阐明其含义。

假设我们有三个按钮。为了清楚起见,我们将它们标为“1”、“2”和“3”。我们希望保证这些元素以正确的数字升序被遍历。为此,我们将 after 和 before 值设置为 2。2 的accessibilityTraversalBefore值将是 1,因为我们希望 1 在 2 之前被遍历。所以这使得 2 的accessibilityTraversalAfter值为 3,因为我们希望 3 在 2 之后到来。创建它的 XML 可以在清单 4-13 中看到。

<Button
      ...
      android:id="@+id/button1"
      android:text="@string/one" />

<Button
      ...
      android:id="@+id/button2"
      android:accessibilityTraversalAfter="@id/ button3"
      android:accessibilityTraversalBefore="@id/ button1"
      android:text="@string/two" />

<Button
      ...
      android:id="@+id/button3"
      android:text="@string/three" />

Listing 4-13Setting accessibility traversal order in XML

您也可以在代码中用setAccessibilityTraversalAfter()setAccessibilityTraversalBefore()方法设置这些,并传递您想在之前/之后访问的视图的id,如清单 4-14 所示。

two.setAccessibilityTraversalAfter(one.id)
two.setAccessibilityTraversalBefore(three.id)

Listing 4-14Setting accessibility traversal order in Kotlin

方向控制

在可访问性遍历顺序中,我们需要设置焦点顺序。当用户使用方向键、遥控器或键盘箭头键导航用户界面时,Android 使用焦点顺序。我们将这些设置在一个元素上,以指定当用户按下特定方向的键时,下一个应该关注哪个元素。处理箭头键输入的属性有nextFocusDownnextFocusUpnextFocusLeftnextFocusRight,处理 tab 输入的属性有nextFocusForward

对于这个例子,假设我们有一个编号为 1 到 9 的 3 乘 3 的元素网格(图 4-9 )。如果我们在中心元素,5 号呢?我们需要保证上移到 2,下移到 8,左移到 4,右移到 6,向前也移到 6。我们的中心元素(编号 5)的 XML 如清单 4-15 所示。

<Button
      android:id="@+id/button5"
      android:nextFocusUp="@id/button2"
      android:nextFocusDown="@id/button8"
      android:nextFocusLeft="@id/button4"
      android:nextFocusRight="@id/button6"
      android:nextFocusForward="@id/button6"
      android:text="@string/five" />

Listing 4-15Setting directional focus in XML

或者,如果我们需要在我们的应用代码中改变这一点(清单 4-16 ,我们也可以在这里设置这些值,传递我们希望在每个方向下一次聚焦的视图的id

button5.nextFocusUpId(button2.id)
button5.nextFocusDownId(button8.id)
button5.nextFocusLeftId(button4.id)
button5.nextFocusRightId(button6.id)
button5.nextFocusForwardId(button6.id)

Listing 4-16Setting directional focus in Kotlin

对于方向控制,我们还需要考虑另一个问题。在 Android 的这个功能的标准实现中,默认的焦点高亮不容易区分(图 4-10 ),这意味着我们必须添加自己的。

最好的方法是在 styles.xml 文件中覆盖应用主题的colorControlHighlight,如清单 4-17 所示。

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
      ...
      <item name="android:colorControlHighlight">@color/colorAccent</item>
</style>

Listing 4-17Setting our app’s theme’s control highlight color to our accent color

自定义控件

如果你坚持在应用中使用 Android 提供的控件,Android 会为你处理可访问性事件。如果您想要自定义控件,请选择与您想要实现的功能最接近的现有控件,并在其上构建。虽然有时你别无选择,只能从头开始建立控制。虽然从可访问性的角度来看不建议这样做,但是对于复杂的元素来说,这有时是必需的。如果您选择这样做,那么用不同的可访问性服务彻底测试您的控件是非常必要的。

首先,您需要确保您已经实现了本章中介绍的大多数属性。一旦你设置了这些值,Android 提供了关于你可能需要在你的控件上覆盖的其他功能的完整文档。 8 你需要实现哪些方法将取决于你的控制,但是我们将在这里讨论一些最重要的。

辅助功能操作

AccessibilityNodeInfo也是我们需要告诉 Android 辅助技术可以在我们的视图上执行的操作的地方。这是我们向客户提供更多信息的机会,让他们了解我们的控制能够做什么以及如何做。

如果你把焦点放在一个有对讲功能的按钮上,一旦该元素的值被读取,对讲功能就会显示“双击激活”。这是一个可访问性操作,由两部分组成。这个按钮告诉 Android 它能够处理一个onClick事件。从这条信息中,Android 添加了“双击以”那么“激活”就是按钮提供的一个字符串。我们需要模仿这个来控制自己。假设我们有一个新的控件,它在一个点击事件上打开一个细节视图,并在一个长按上显示一个选项菜单。我们的代码如清单 4-18 所示。

class MyView: View {

    constructor(context: Context, attrs: AttributeSet): super(context, attrs)

    override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo?) {
        super.onInitializeAccessibilityNodeInfo(info)

        val click = AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, "open")

        val longClick = AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_LONG_CLICK, "show options")

        info?.addAction(click)
        info?.addAction(longClick)
    }
}

Listing 4-18Adding accessibility actions to a custom view

事件处理

虽然在视图中添加一个setOnClickListener()可能会使它在客户点击屏幕时正常工作,但这并不能保证您的视图会正确响应语音访问、对讲或其他辅助服务。你应该测试你是否需要覆盖sendAccessibilityEvent()或者sendAccessibilityEventUnchecked()函数。这些方法在每次视图上触发辅助功能事件时被触发,包括聚焦和点击。

根据您的视图是如何创建的,Android 可能已经如您所料为您处理了激活事件。对于像关注具有可访问服务的元素这样的事件,您可能需要对视图进行更改,例如添加高亮显示。您可以通过检查事件是否与可访问性焦点相关来做到这一点,如清单 4-19 所示。

class MyView: View {

    constructor(context: Context, attrs: AttributeSet): super(context, attrs)

    override fun sendAccessibilityEvent(eventType: Int) {
        super.sendAccessibilityEvent(eventType)

        when (eventType) {
             AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED ->
                background = Color.BLACK.toDrawable()

             AccessibilityEvent.TYPE_VIEW_FOCUSED ->
                background =
                Color.RED.toDrawable()
        }
    }
}

Listing 4-19Setting the background color of a view red when it receives accessibility focus. Black when focus leaves the view

文本更改事件

每当控件的文本值改变时,辅助功能服务都需要知道这一点。这有助于 Android 确保呈现给辅助功能用户的内容与屏幕上显示的内容相同。为此,您的定制视图必须通过发布一个TYPE_VIEW_TEXT_CHANGED的可访问性事件(清单 4-20 )来通知 Android 值已经更改。

sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED)

Listing 4-20Informing accessibility about a text change on our custom view

节点信息

为了知道如何将你的视图呈现给可访问性用户,Android 收集了关于你的视图及其当前状态的信息。这包括视图的大小和位置。当 Android 请求这些信息时,它在您的视图上调用onInitializeAccessibilityNodeInfo(),传递一个初始化的AccessibilityNodeInfo供您填充(清单 4-21 )。你应该总是在这里调用 super 来让 Android 填充一些明智的默认值。然后,您可以添加控件需要的任何其他属性。这可能包括像isHeadingisCheckable这样的属性。

class MyView: View {

    constructor(context: Context, attrs: AttributeSet): super(context, attrs)

    override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo?) {
        super.onInitializeAccessibilityNodeInfo(info)

             // Accessibility services will treat your view as toggleable.
        info?.isCheckable = true
    }
}

Listing 4-21Adding properties to our custom view’s accessibility info

代表

如果您选择使用提供的 Android 控件,但是希望对每个控件的可访问性如何工作有更细粒度的控制,那么您可以使用一个AccessibilityDelegate类。创建一个扩展AccessibilityDelegate的类;然后将其设置为视图上的代表(列表 4-22 )。委托可以覆盖我们之前介绍过的相同的可访问性方法。

class MyAccessibilityDelegate : View.AccessibilityDelegate() {

    override fun onInitializeAccessibilityNodeInfo(host: View,
       info: AccessibilityNodeInfo) {
        super.onInitializeAccessibilityNodeInfo(host, info)

        // add custom actions
    }
}

class MyActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.my_activity)

        val accessibilityDelegate = MyAccessibilityDelegate()

        button.accessibilityDelegate = accessibilityDelegate
       }
}

Listing 4-22Setting an accessibility delegate

语义视图

创建语义视图是一种强大的高级技术,可以创建最容易访问的应用。语义视图将两个或更多有关联意义的元素联系在一起。Android 然后将它们作为一个元素呈现给可访问性用户。这可以减少噪音,让你的应用导航更加简单、快速、轻松。如果你真的想给你的可访问性用户最好的体验,你需要使用这种技术。

谷歌在谷歌 Play 商店使用了这种技术。当查看一个应用或游戏的列表页面时,我们会在该应用的图标下看到三个框(图 4-11)——该应用的评级、下载次数和年龄评级。第一项,应用的评级,显示“4.4 ⭑”,然后在新的一行“1K 评论”此外,评级文本和年龄评级文本是按钮。如果您在启用 TalkBack 的情况下访问这些元素,而不更改可访问性树,则 TalkBack 将读取以下内容:

img/486920_1_En_4_Fig11_HTML.jpg

图 4-11

谷歌 Play 商店应用信息

img/486920_1_En_4_Fig10_HTML.jpg

图 4-10

突出日期的键盘导航——你可能看不出日期周围有方框

img/486920_1_En_4_Fig9_HTML.jpg

图 4-9

由九个按钮组成的网格。我们希望确保从数字 5 开始,方向导航就像预期的那样工作

img/486920_1_En_4_Fig8_HTML.jpg

图 4-8

三个按钮。我们希望确保它们按数字顺序导航

  • “四点四星。双击以激活。”刷卡。

  • " 100 K 加"游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游啊游。

  • “1 K 评论。”刷卡。

  • "下载。"刷卡。

  • “PEGI 3 号。双击以激活。”

刷的真多。刷一下,我们只听到“下载”这个词 100K 指的是什么?幸运的是,这不是 TalkBack 展示这一观点的方式。谷歌 Play 商店开发人员已经改进了他们的可访问性树,以提供更好的体验。相反,这是互动:

  • “一千条评论平均评分四点四星。双击以激活。”刷卡。

  • “下载了十万多次。”刷卡。

  • “内容分级 PEGI 3。双击以激活。”

将这些元素组合在一起有几个好处。首先,需要更少的刷卡次数,从五次减少到三次。意味着导航更快更简单。与分组相关的元素,如应用评论值和评论数量,提供了每个值的含义。通过将“100,000 plus”改为“100,000 plus ”,该文本也被修改为对对讲客户更有意义虽然从视觉上可以清楚地看到 K 代表千,但我们很少大声说出 K 代表千。

可聚焦容器

实现这一点的最简单的方法之一是使用可聚焦的容器。布局容器如LinearLayoutRelativeLayout是不可见的,并且不包含任何内容。但是它们包含属性,我们可以设置这些属性,使它们出现在诸如 TalkBack 之类的可访问性服务中。以谷歌 Play 商店的应用评级为例。如果我们想要实现类似的东西,我们可以使用垂直线性布局,如清单 4-23 所示。

<LinearLayout
      ...
      android:orientation="vertical">

      <TextView
           ...
           android:text="@string/rating” />

      <TextView
           ...
           android:text="@string/number_of_reviews" />
</LinearLayout>

Listing 4-23A vertical linear layout with text

目前,这个视图需要两次滑动才能进行对讲导航,可能不清楚等级值指的是什么。为了清楚起见,让可访问性服务把这个视图看作一个单独的元素。为此,我们可以将线性布局的 focusable 属性设置为 true。你可以用代码(清单 4-24 )或者直接用我们的 XML(清单 4-25 )来实现。

<LinearLayout
      ...
      android:focusable="true"
      android:orientation="vertical">

      ...

</LinearLayout>

Listing 4-25Setting a linear layout focusable in XML

linearLayout.focusable = View.FOCUSABLE

Listing 4-24Setting a linear layout focusable in Kotlin

这里的结果是每个单独的文本视图不再显示为对讲。相反,线性布局是重点,Android 已经将文本视图的值传递给线性布局。这是一个惊人的改进,但是我们仍然有一个关于读取信息的问题。我们的客户听到的不是“10 万条评论”,而是“10 万条评论”因此,让我们删除可聚焦的值,代之以将内容描述传递给线性布局。我们将在本章前面的内容描述部分介绍如何做到这一点。不要只是连接两个可视的字符串,而是生成一个新的可访问的字符串,在大声朗读时更有意义。有了内容描述,我们的线性布局已经自动隐藏了其子元素。相反,布局元素是重点,我们的新内容描述朗读。

摘要

  • Android 的可访问性服务使用一种称为可访问性树的技术来理解你的应用的 UI。这是为您构建的,但您需要调整它,以确保它对您的客户有意义。

  • 尽可能坚持使用 Android 提供的视图和控件。创建自己的控件时,可访问性很复杂。Android 已经为你做了很多艰苦的工作。

  • 将连接的视图组合成语义视图。这将使你的应用使用起来更快,更容易理解。

在这一章中,我们讨论了 Android 的可访问性系统是如何在底层工作的。您现在对如何制作一个与辅助技术共生的界面有了更清晰的想法。让我们仔细看看 Android 为我们的客户提供的一些辅助功能。我们还将讨论作为开发人员需要做出的一些决定,以便为依赖他们的用户提供最好的支持。

Footnotes 1

https://material.io

  2

https://material.io/components/

  3

谷歌也为 iOS 提供了材质设计,但这是错误的一致性类型。在 iOS 上使用材质设计意味着用户在进入/离开你的应用时有更大的上下文切换。在 iOS 上使用材质设计会导致 app 的易用性降低。谷歌在 Material Design 的可访问性指南中对此提出了警告,同时鼓励 Material Design 在 iOS 上的使用。☺

  4

https://material.io/design/introduction/

  5

https://material.io/design/usability/accessibility.html

  6

https://developer.android.com/guide/topics/ui/accessibility/service

  7

https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html

  8

https://developer.android.com/guide/topics/ui/accessibility/custom-views

 

五、Android 辅助功能

在这一章中,我们将看看 Android 的辅助功能。这不是一个详尽的指南;我们将把重点放在可能影响你作为开发人员的特性上,因为你需要提供支持,为特性的工作做出一些决定,或者因为它可能以某种方式改变你的应用的外观或感觉。有关更多以消费者为中心的可用功能介绍,请查看谷歌的支持页面。 1

Android 的辅助功能因设备和供应商而异,平台上的许多功能也是如此。还可以通过谷歌 Play 商店添加第三方辅助工具。可访问性的一个主要方面是可定制性。对于用户来说,能够选择具有适合他们的功能的设备,然后根据需要添加和定制这些功能是一种优势。但是这确实意味着您的开发目标是一个移动的目标,所以跨设备的手动测试是必不可少的。作为本章的参考设备,我使用的是运行 Android 10 的谷歌 Pixel。

特征

设备的辅助功能设置是“系统设置”应用中的顶级选项。当你切换它的时候,Android 立即启用这个菜单中的每个选项。大多数都提供了一个简短的文本描述,说明定制做了什么以及如何做。许多网站提供了一个你正在做的改变的可视化例子,有些甚至是一个教程。这些设置都不是破坏性的,您可以通过关闭来再次禁用它们。所以我建议花几分钟时间熟悉一下这些设置的内容。尝试启用每一个;反过来,打开设置导航你的应用,看看它给你的体验带来了什么变化。你的应用还能像你期望的那样工作吗?也许你会发现,在启用这些考虑因素的情况下,你可以通过使用你的应用快速取胜。其中一些设置,如对讲,会改变您与设备的交互方式。有必要先了解一下这些特性。但如果你想陷进去,Android 会在你第一次切换 TalkBack 时给你一个全面的教程。这些辅助功能设置都是关于可定制性的,因此您可能会找到想要在自己的设备上启用的设置。

音量键快捷键

音量键快捷键是测试你的应用的绝佳工具。它允许您快速启用和禁用选定的辅助功能服务。立即在您设备的设置中启用此服务。当我们讨论不同的服务时,请在服务设置中更改此快捷方式切换的服务。这样,无论您身在何处,都可以顺畅地访问该服务,而无需在设置间来回导航。启用后,按住设备的两个音量键 3 秒钟,以切换您选择的辅助功能服务。

可用选项因设备而异,但包括设备上安装的大多数辅助功能服务。我们将在本章的后面讨论这些特性。现在,我建议切换到对讲。这样,您就有了一个快速、简单的方法来为可访问性测试启用对讲。这将有助于使屏幕阅读器设备测试成为开发流程中的常规部分。

对讲系统

当我们谈论移动设备的可访问性时,我们经常用可访问性这个词来代表屏幕阅读器导航服务,比如 TalkBack。如果你知道一个 Android 可访问性服务,它很有可能是 TalkBack。

Tip

启用该服务前,请阅读对讲导航部分。

TalkBack 是 Android 内置的屏幕阅读器服务。它使盲人和弱视用户能够听到屏幕上的内容,但它不仅仅是一个屏幕阅读器。通过宣布控件并允许用户通过定义的手势与它们交互,TalkBack 允许您的客户导航他们的整个设备,而不必看到屏幕(图 5-1 )。您的应用已经与 TalkBack 兼容,无需您进行任何设置。但是你的应用和 TalkBack 配合的如何是一个不同的问题。Android 的内置控件都是在考虑 TalkBack 的情况下创建的。因此,如果您已经使用这些控件作为基础,您可能会发现它的效果比您在做出任何改进之前可能预期的要好。

img/486920_1_En_5_Fig1_HTML.jpg

图 5-1

对讲突出显示显示设置并读取控制内容

TalkBack 要求元素具有文本表示,以便客户可以阅读该元素。对讲系统读取的信息及其顺序因元件而异。默认情况下,如果元素有文本值,TalkBack 将读取它。如果你的元素的文本很短,它可能缺少视觉用户从它周围的元素中得到的上下文。如果元素的文本很长,对于对讲用户来说可能太冗长了。在这种情况下,内容描述,一个简短的描述可访问性的字符串,可能会更好。如果存在,Android TalkBack 读取内容描述而不是文本值。TalkBack 遵循文本或内容描述,在出现时带有提示或角色;顺序取决于元素的状态和类型。我们在前一章中已经详细介绍了这些。虽然 TalkBack 只是一种可访问性服务,但它使用的可访问性树与其他服务一样。一般来说,如果你的应用和 TalkBack 配合得很好,你会发现其他辅助服务也可以。

出于测试和学习的目的,我还建议启用显示语音输出设置。你可以在开发者设置下的对讲设置中找到。这将在屏幕上显示一段当前正在朗读的祝酒辞。这将有助于您准确理解您向客户展示的内容。

Android 提供了一种简单的方法来检测可能影响应用功能的典型屏幕阅读器功能。TalkBack 允许用户与屏幕上的元素进行交互,而无需激活它们。这是通过在屏幕或特定元素上点击或执行触摸手势来完成的。这意味着这些手势不会传递到你的应用,元素的激活方式也不同。因此,了解您客户的设备是否启用了此功能可能会很有用,因为您可能需要调整您的应用如何使用触摸手势。你可以通过查询 Android 的AccessibilityManager(清单 5-1 )上的isTouchExplorationEnabled属性来实现。

val a11yManager = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
val isExploreByTouchEnabled = a11yManager.isTouchExplorationEnabled

Listing 5-1Determining if explore by touch is enabled

有关检测对讲或其他辅助功能服务是否启用的详细信息,请参阅本章后面的“检测辅助功能服务”一节。

更新内容

即使有一个完美的可访问性树,你可能会发现有些情况下你需要提醒对讲用户屏幕上的视觉变化。这可能是通知您的客户有新消息到达,一个长期运行的任务已经完成,或者一个游戏的分数已经改变。有两种方法可以做到这一点。但是在您决定添加任何一个功能之前,请考虑您是在为您的客户增加价值还是仅仅增加噪音。

宣布可访问性

在任何时候你都可以告诉 TalkBack 用announceForAccessibility()方法宣布你传递的任何字符串(列表 5-2 )。此方法在任何视图上都可用。

myView.announceForAccessibility("New message received")

Listing 5-2Making TalkBack announce the screen has changed

实时区域

实时区域是屏幕上更新内容与对讲用户交互分开显示的区域。一个例子可以是显示的过滤的搜索结果的数量的计数器。在搜索字段中键入时,客户会想知道他们键入的每个字符返回的结果是多了还是少了,但是在搜索字段中输入和输出每个字母会很费力。

在这些情况下,您可以将结果计数器标记为活动区域(清单 5-3 和清单 5-4 )。实时区域将在每次更新时宣布其内容,无需您的客户进行任何进一步的交互。实时区域有两种可能的模式:politeassertivepolite将在任何当前话语结束后阅读内容。assertive将中断任何现有的公告;除非绝对必要,否则避免这些。

resultsCounter.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE

Listing 5-4Creating a live region in Kotlin

<TextView
     ...
     android:accessibilityLiveRegion="polite" />

Listing 5-3Creating a live region in XML

Navigating With Talkback

TalkBack 改变了与应用交互的模式。一旦您在设备的可访问性设置中启用了此服务,TalkBack 即开始运行。因此,你必须了解它对你与你的设备交互方式的改变,尤其是当你完成时,你可以关闭这个功能!

TalkBack 以自然的方向导航你的用户界面的所有可读元素——在大多数语言中是从左上到右下——在前进的过程中用一个边框高亮显示每个元素。您可以通过点击来选择元素;一次点击将不再激活控件。向右滑动屏幕上的任意位置以导航到下一个元素,或者向左滑动以导航到上一个元素。要激活控件,您现在必须双击。

img/486920_1_En_5_Fig2_HTML.jpg

图 5-2

安卓的 TalkBack 教程应用

幸运的是,TalkBack 有一个奇妙的教程应用,允许你练习使用屏幕阅读器的功能。如果这是第一次在该设备上激活 TalkBack,只要您打开该服务,TalkBack 就会启动其教程(图 5-2 )。如果之前已经启用对讲,可以手动开始本教程。在列表底部的对讲设置中找到它。要导航到那里,请记住–点击一次以选择一个元素;双击以激活该元素。在滚动视图上向右然后向左滑动以向下翻页。在尝试使用 TalkBack 之前,请先完成教程;会让你以后少受很多挫折。

选择发言

与 TalkBack 相比,Select to Speak 是一个更“传统”的屏幕阅读器。选择朗读将按照文本内容出现的顺序朗读屏幕上出现的任何文本内容。“选择说话”不提供任何导航或与应用交互的帮助。这使得它成为那些因为视力低下、诵读困难或识字率低而难以阅读的人的理想工具。

与 TalkBack 相比,Select to Speak 在阅读内容、阅读方式和阅读时间方面有所不同。这个工具的目的是帮助处理大量的文本,例如一篇文章或电子书,或者更大篇幅的文本。选择朗读不是为了帮助导航或暗示布局的含义。因此,选择朗读会读取屏幕上显示的内容,忽略您对辅助功能树所做的任何更改。这包括忽略分组的元素和内容描述,除非具有内容描述的元素没有其他文本表示。例如,在谷歌 Play 商店上,TalkBack 会将应用的评级读作“来自 1200 万条评论的四点二星”,Select to Speak 会读作“四点二星”。十二 M 评论。”

img/486920_1_En_5_Fig3_HTML.jpg

图 5-3

选择以启用朗读,同时选择一个区域进行阅读

选择“朗读”会在屏幕的右下角添加一个辅助功能按钮。点击它,用户有两种选择:按下播放按钮以自然阅读方向阅读整个可见屏幕,或者在屏幕的一个区域上拖动手指(图 5-3 )。第二个选项绘制一个边界框;选择朗读朗读边界框区域内的任何元素。

字体大小

Android 原生支持全局缩放字体大小,以适应您客户的偏好(图 5-4 )。选项的数量因供应商而异,但谷歌的 Pixel 设备支持四种设置,从小到大。

img/486920_1_En_5_Fig4_HTML.jpg

图 5-4

Android 的最小(左)和最大(右)字体大小。外观因设备而异

你可以使用与缩放无关的像素在你的应用中实现自动字体缩放;你会在布局文件中看到这些“sp”单元(列表 5-5 )。SP 单位代表像素,但有一些可变元素。这允许设计者指定字体大小,比如 14px 然后我们可以将它作为 14sp 输入到 XML 中。在标准文本大小下,这将显示为相当于 14px。

<TextView
      ...
      android:textSize="14sp"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"  />

Listing 5-5Setting text size by scale-independent pixels

sp 单元的可变元素首先是屏幕密度。1sp 在 160 dpi(每英寸点数)屏幕上的默认文本大小相当于 1 个像素。具有更高或更低 dpi 的屏幕被适当地放大或缩小。一个固定的像素数字在不同的 dpi 中会显得更大或更小,而一个 sp 单位看起来应该大致相同。第二,sp 单位由用户选择的字体大小设置按比例缩放。这意味着确保所有文本都设置为 SP 单位将保持视图的外观,同时支持辅助功能。

为了充分支持用户不同的文本大小和屏幕密度,一个相关的考虑因素是您为显示文本的元素提供的大小。避免使用固定的高度或宽度尺寸,而是提供wrap_content。使用和组合布局,如线性布局和约束布局,将允许文本元素-编辑文本,按钮,文本视图等。–根据需要进行扩展和收缩,同时保持您的预期设计。任何包含文本的元素都应该显示在滚动视图中。这将确保用户使用任何给定的文本大小、屏幕大小、屏幕密度等组合。仍然可以阅读您的所有内容。

显示尺寸

Android 支持各种屏幕形状和尺寸的能力使其能够无摩擦地支持另一个辅助功能:可调显示屏尺寸(图 5-5 )。这对于你的应用来说是无缝的,只要你遵循一些简单的设计准则:避免固定大小的元素,更喜欢wrap_content。使用灵活的布局,如约束布局。将文本内容放在滚动视图中,并使用相对单位而不是固定单位。

例如,像素的物理大小在不同的屏幕分辨率下会有所不同,而毫米在不同的设备上具有固定的大小,但在屏幕上占据的空间大小会有所不同。相反,如果您使用 sp 单位(与比例无关的像素)为文本大小定义所有布局尺寸,使用 dp 单位(与密度无关的像素)为非文本值定义所有布局尺寸,效果会更好(清单 5-6 )。这些值根据环境变量按比例缩放。这些变量包括客户对文本大小和显示大小的设置,以及他们设备的像素密度。

<Button
      ...
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:textSize="24sp"
      android:padding="16dp" />

Listing 5-6Defining a button’s text size and padding using sp and dp units

使用 sp 和 dp 单元将在用户的各种设备上保持您的屏幕布局,并支持缩放的屏幕尺寸和缩放的文本,从而在保持高标准设计的同时帮助您的客户。

img/486920_1_En_5_Fig5_HTML.jpg

图 5-5

Android 的最小(左)和最大(右)显示屏尺寸。外观因设备而异

黑暗主题

Android 10 的新主题是黑暗主题。我知道很多开发者喜欢有黑暗主题的界面。因为我们要花几个小时看屏幕,如果没有白光照射,我们的眼睛会有很大的不同。另外,它看起来真的很酷。但是深色主题也是一个重要的辅助功能。大量明亮的光线对于患有特定视力问题(如白内障)的人来说可能是一个问题,因为光线会导致不适,并破坏人的其余视力。深色主题的高对比度也可以让色觉减退或视力模糊的人更容易区分元素。因此,虽然很容易认为深色主题很好,但对许多人来说,这是一个基本的可访问性特性。

支持黑暗主题需要对你的应用进行一些更改。首先,如果你还没有,你需要编译 API 级。支持黑暗主题的最快方法是通过将清单 5-7 中的代码行添加到 styles.xml 文件中的应用主题中来强制应用支持黑暗模式。

<style name="AppTheme"
      parent="Theme.MaterialComponents.Light.DarkActionBar">
      ...
      <item name="android:forceDarkAllowed">true</item>
</style>

Listing 5-7Forcing dark theme support for an app style

你可能会发现这适用于你的应用,但这是一个相当生硬的工具。我们正在使用我们的原始主题结合 Android 的默认黑暗主题行为。我们无法控制我们的应用如何处理黑暗主题。我们有可能需要对事物的外观进行更精细的控制。

Android 让我们能够为调色板中定义的每种颜色定义黑暗或夜晚的变化。在 Android Studio 中,在项目导航器中找到 res 目录。点击右键,选择新建➤安卓资源文件。将文件命名为颜色——我们已经有了一个同名的文件,这没关系;我们在做一个夜间变体。在可用限定符下找到夜间模式(图 5-6 ,并按下添加按钮选择它。在现在出现的夜间模式下拉框中,将值更改为“Night”,然后按 OK。

img/486920_1_En_5_Fig6_HTML.jpg

图 5-6

创建夜间模式颜色文件变体

然后你会发现你现在有两个颜色文件出现在你的项目导航器中。一个后缀为*(夜)*。(图 5-7)

img/486920_1_En_5_Fig7_HTML.jpg

图 5-7

Android Studio 的项目导航器中的两个颜色值 XML 文件。一个是夜间变体

appear in your project navigator. One with the suffix “

在这个新的 night variant 文件中,您可以从需要深色主题变量的原始颜色值文件中复制任何颜色值。例如,如果你的标准背景颜色是<color name="background_color">#FFFFFF</color>,你可以把它作为<color name="background_color">#FF808080</color>添加到你的夜间模式文件中。这将使你的背景在黑暗模式下变成深灰色,而不是 Android 默认的黑色。任何你不抄袭安卓的颜色都会为你调整。为了做到这一点,我们需要确保我们没有在任何布局 XML 文件或应用代码中使用任何硬编码的颜色值。总是在你的 colors.xml 文件中定义颜色,然后通过名称引用这个定义的颜色,如清单 5-8 和清单 5-9 所示。

val color = getColor(R.color.background_color)

Listing 5-9Referencing our background color value in code

<LinearLayout
      ...
      android:background="@color/background_color" >

Listing 5-8Referencing our background color value in a layout

放大

Android 有两个放大服务。放大的结果是一样的;区别在于它们是如何被触发的。顾名思义,你可以通过在屏幕上的任何地方点击三次来切换放大。使用快捷方式放大(图 5-8 )在屏幕右下角添加一个辅助功能快捷按钮,作为导航栏的一部分。轻按按钮一次,打开或关闭放大功能。

img/486920_1_En_5_Fig8_HTML.jpg

图 5-8

通过辅助功能按钮启用快捷方式放大

Android 开发人员需要注意放大有两个原因,第一个原因可能会影响任何应用。由于文本是从左到右书写的,任何放大用户通常会从屏幕的左侧向下扫描(或者在从右到左语言的情况下从右侧向下扫描)。这意味着如果你有不自然(左)对齐的内容,放大用户通常会错过这一点。例如,如果您在表格的某一行旁边添加一个表示状态的图标,如果您的图标位于文本的右侧,放大用户可能不会注意到状态图标(图 5-9 )。在可能的情况下,保持任何有意义的内容自然对齐。

img/486920_1_En_5_Fig9_HTML.jpg

图 5-9

启用放大功能导航辅助功能设置。任何右对齐的内容都可能会丢失

开发人员应该注意的另一个放大功能是使用的手势。三次点击放大将覆盖您的应用侦听的任何三次点击事件,这意味着如果启用放大,您的应用将不会接收到任何三次点击手势,即使您的用户没有激活取景器。激活后,放大功能使用两个手指滑动来移动取景器,两个手指挤压手势来放大和缩小。这意味着一旦放大功能激活,您的应用将不会收到两个手指滑动或挤压手势。解决这一问题的理想方法是,在适当启用或激活放大功能后,修改应用使用的手势。不幸的是,就目前情况来看,我还没有找到一种方法来检测这些放大服务是否处于活动状态。本章后面提到的检测放大服务的方法似乎没有返回这些服务中的任何一个。对于希望手势在你的应用中工作的放大用户来说,这可能意味着令人沮丧的体验。这只是为什么你应该为你的应用使用的任何触摸手势提供替代品的一个原因。

颜色校正

色彩校正提供了一系列滤镜,旨在帮助有色彩缺陷的用户。这些滤光器有助于增加对比度,并使颜色远离那些不足会导致区分问题的颜色。Android 通过全局覆盖来实现这一点,因此开发人员不需要做任何工作来支持颜色校正。

然而,你应该尝试应用中可用的每个滤镜,以确定每个滤镜的对比度是否仍然足够高,并看看是否仍然有可能在需要的地方从颜色使用中获得意义。你应该避免把颜色作为传达意思的唯一方式,也不要把文字和形状结合起来。一个很好的例子就是状态指示器;用绿色圆圈和红色感叹号代替红色或绿色圆圈。

颜色反转

反转颜色对几种损伤有好处。它可以减少眩光,提高对比度。这意味着光敏感、色弱或视力下降的人都可以受益于这一功能。颜色反转反转屏幕上的所有颜色。这与它们在哪里或如何使用以及应用如何设置无关。这包括图像和视频。一些用户会从倒置的图像中受益,但对许多人来说,它看起来很奇怪。如果可能的话,对你的客户来说更好的体验是支持黑暗主题。使用前面提到的深色主题,你可以选择应用反转的颜色以及反转的方式,从而在保持应用美观的同时,获得可靠的可访问体验。

移除动画

动画会引发平衡障碍患者的眩晕和恶心。对于有某些学习困难或障碍(如注意力障碍、自闭症和焦虑)的人来说,动画也可能令人担忧和分心。出于这些原因,有必要听取这个设置,并使用它来确定您是否应该减少或删除动画。启用此设置后,您应该查看应用中具有快速动画、多平面动画、缩放动画和自动播放视频的地方。

没有友好的布尔值来确定您的用户是否启用了该设置,但是如果该设置为 on,则ANIMATOR_DURATION_SCALE设置将返回浮点值 0。因此,我们可以使用清单 5-10 中的代码将它转换成我们可以在代码中使用的布尔值。

private fun areSystemAnimationsEnabled(): Boolean {
      val animationDuration = try {
           Settings.Global.getFloat(contentResolver,
      Settings.Global.ANIMATOR_DURATION_SCALE)
      }
      catch (e: Settings.SettingNotFoundException) {
           0f
      }

      return animationDuration != 0f
}

Listing 5-10A method returning false if the user has requested animations removed

切换访问

Switch access 是一项辅助功能服务,旨在通过允许您的用户使用外部硬件设备来导航和控制您的界面,从而帮助运动能力有限的人。开关可以是许多东西,例如,一个普通的键盘。也可以购买专门为此目的设计的第三方交换机。

Tip

在启用该服务之前,请阅读有关使用交换机访问进行导航的章节。

切换访问用边界框依次突出显示每个交互元素。然后,用户可以按下一个开关,跳到下一个元素或激活当前选定的元素。使用一个按钮进行导航非常耗时,这意味着交换机访问用户通常最容易受到应用超时的影响。尽可能考虑延长或取消超时。

img/486920_1_En_5_Fig10_HTML.jpg

图 5-10

切换访问突出显示一行应用

为了实现这种控制,交换机访问可访问性服务使用第四章中讨论的可访问性树。这与 TalkBack 等其他服务使用的可访问性树相同。因此,如果你的应用与 TalkBack 配合得很好,那么它与 Switch Access 配合得也很好。与 TalkBack 相比,Switch Access 只关注交互元素(图 5-10 )。因此,您的交互元素必须正确设置。使用 Android 的内置控件,如按钮和编辑文本控件,在需要的地方进行扩展,而不是实现自己的控件。例如,如果您使用一个图像并添加了一个onTouchListener,切换访问将不会访问这个触摸监听器。请改用图像按钮控件。

Navigating With Switch Access

第一次启用交换机访问时,Android 会向您呈现一个设置指南(图 5-11 )。该应用将带您完成交换机访问配置,然后为您提供一个测试区域,让您习惯交换机访问如何使与您的设备的交互变得不同。

img/486920_1_En_5_Fig11_HTML.jpg

图 5-11

交换机访问设置指南

首先,连接一个开关。虽然有专门用于开关访问的开关,但我建议使用键盘进行测试;无论是 USB 还是蓝牙都是最好的入门方式。

根据您想要使用的开关数量选择控制模式(图 5-12 )。我建议尝试这两种模式,这样你就可以了解你的 Switch Access 用户会如何体验你的应用。

img/486920_1_En_5_Fig12_HTML.jpg

图 5-12

选择可用于交换机访问的交换机数量

选择一个开关,按一下开关开始扫描屏幕。边界框高亮将在交互元素之间自动移动。按下一个元件上的开关来激活它。这种形式的互动需要很长时间,但对于行动最受限的人来说是必不可少的。

两个开关是更直接、更快速的导航模式,因为它完全按照用户的节奏来完成。一个开关导航到下一个交互元素,第二个开关激活该元素。暂时选择此选项。

接下来,选择您的扫描模式(图 5-13 )。线性扫描 2 从左上到右下依次高亮显示每一个交互元素。这种模式可能会慢一些,因为我们必须访问屏幕上的每个元素,但它可以防止一些意外的按压。行-列扫描将按行对元素进行分组。这使得浏览某些屏幕更快。按下“下一个”开关将导航到下一行元素,而不是下一个元素。如果您想要激活该行中的某个元素,请按下选择开关。然后使用“Next”开关导航到该行中您想要激活的元素。

img/486920_1_En_5_Fig13_HTML.jpg

图 5-13

在交换机访问设置中选择扫描模式

接下来的两个屏幕包括选择您的两个开关。在你的键盘上选择任意两个键,但是我建议两个相邻的键。

最后,我们会看到一个井字游戏来帮助我们练习(图 5-14 )。按下分配给你的“下一步”键开始扫描。如果你坚持使用这个设置导航,或者想尝试一些不同的东西,请按“上一步”(屏幕仍然可以使用常规触摸输入)并重新配置。在禁用开关访问之前,请记住也使用它来导航您的应用。

img/486920_1_En_5_Fig14_HTML.jpg

图 5-14

用井字游戏练习交换机访问

如果你喜欢冒险,试试开关访问设置中的其他选项。它们对你的应用界面呈现给用户的方式都有显著的影响。我建议查看以下内容:

  • 语音、声音和振动

    在此菜单中启用语音反馈。这种模式通过大声读出所有可表示文本的元素,将对讲功能与开关访问功能结合起来。这意味着切换控制将在导航时关注所有元素,而不仅仅是交互元素。

  • 自动扫描

    当开关访问配置为一个按钮时,自动扫描会以秒为间隔自动从一个元素导航到下一个元素。

  • 点扫描

    A horizontal line scans from the top of the screen to the bottom; press Select to stop (Figure 5-15). A vertical line then moves from left to right. Press Select when the crosshairs are over the element you want to activate.

    img/486920_1_En_5_Fig15_HTML.jpg

    图 5-15

    在点扫描模式下切换访问,选择驱动程序

触摸并保持延迟

触摸并保持延迟调整触发长按事件所需的时间。这有助于控制意外按压。如果您使用onLongClickListener确定长按,该设置将被考虑在内。使用这个监听器,而不是尝试自己为长点击计时。

是时候采取行动了

采取行动的时间,也称为可访问性超时,给用户额外的时间来查看临时的可视元素,并在需要时对它们采取行动。辅助功能用户浏览应用的速度通常比非辅助功能用户慢。有时候这是因为他们的能力;其他人,这是他们选择的辅助技术的功能。

该功能提供了从 10 秒到 2 分钟的各种选项。任何随后的烤面包或小吃店将显示用户选择的时间长度,覆盖您在代码中设置的值。如果您已经实现了自己的小吃店类型的控制,您不会得到这种行为。

字幕

Android 原生支持带有VideoView控件的字幕。用户可以在可访问性设置中全局启用这些选项,以及选择尺寸和颜色等选项(图 5-16 )。作为一名开发者,你可以将字幕嵌入到视频轨道中,或者通过 vtt 格式的输入流单独提供——vtt 字幕轨道通常以. srt 扩展名结尾(清单 5-11 )。一旦你这样做了,VideoView将根据你的用户的喜好来处理这些渲染。

img/486920_1_En_5_Fig16_HTML.jpg

图 5-16

Android 的字幕偏好

val subtitlesEN = getResources().openRawResource(R.raw.subs_en_vtt) // this could also be an InputStream instance loaded from a network resource.

videoView.addSubtitleSource(subtitlesEN,
      MediaFormat.createSubtitleFormat("text/vtt",
      Locale.ENGLISH.getLanguage()))

Listing 5-11Loading a subtitles file from resources and adding these subtitles to a VideoView instance

如果您在 VideoView 之外的控件中显示视频,您需要自己负责显示和呈现字幕。您可以使用清单 5-12 中的CaptioningManager类来检索客户的设置。

val captioningManager = getSystemService(Context.CAPTIONING_SERVICE) as CaptioningManager
val captionsEnabled = captioningManager.isEnabled
val captionStyle = captioningManager.userStyle
val textScale = captioningManager.fontScale

Listing 5-12Accessing caption settings from the system’s captioning manager

如上所示,CaptioningManager类提供了一个返回CaptionStyle类对象的userStyle值。这个类提供了诸如字体、前景色和背景色等信息。查看 Android 开发人员文档,了解完整的值范围。 3 你应该尽可能遵循这些偏好,因为你的顾客会选择这种字体、大小、颜色等的组合。是有原因的。

此外,您应该倾听客户字幕设置的变化。CaptioningManager允许我们设置一个CaptioningChangeListener(列表 5-13 ),这样我们就可以在客户更改设置时得到通知。

class MyCaptionListener:
      CaptioningManager.CaptioningChangeListener() {
      override fun onEnabledChanged(enabled: Boolean) {
                 // remove captions from your view
      }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
      val captioningManager = getSystemService(Context.CAPTIONING_SERVICE) as

      captioningManager.addCaptioningChangeListener(MyCaptionListener())
      }
}

Listing 5-13Using a CaptioningChangeListener to detect changes in captioning settings

高对比度文本

高对比度文本使文本变成黑色或白色,这取决于文本的原始颜色。然后添加一个相反颜色的边框(图 5-17 )。这是使用 Android 的常规文本渲染系统完成的,因此在大多数情况下会为您进行处理。AccessibilityManager确实有一个值来检测此功能是否启用。但是,由于不清楚的原因,它对公共接口是隐藏的。因此,如果您选择使用isHighTextContrastEnabled方法,请小心操作。

img/486920_1_En_5_Fig17_HTML.jpg

图 5-17

标准文本(左)和高对比度文本(右)

语音接入

语音访问并不包含在 Android 的标准辅助工具套件中,而是一项辅助工具服务,可以通过搜索语音访问从谷歌 Play 商店免费下载。语音访问允许完全免提访问和控制设备。如果你在开车,这是一个有用的功能,但对于行动不便的人来说,尤其是那些行动最受限但能说话的人来说,这是无价的。语音访问仅使用语音不仅可以执行简单的任务,如谷歌助手,还可以完全控制设备。作为一个重要的辅助功能,语音访问使用起来非常有趣,所以请从 Google Play 下载并查看它。

img/486920_1_En_5_Fig18_HTML.jpg

图 5-18

启用语音访问。用户请求“打开我的应用”

像 Android 上的其他可访问性服务一样,语音访问使用我们在第四章中讨论的可访问性树。为简单起见,语音控制将在每个交互元素旁边显示数字(图 5-18 ),但这些也可以由屏幕上显示的名称触发。TalkBack 将读取元素文本值上的元素内容描述,而 Voice Access 将响应元素的文本值,但不会响应内容描述,因为内容描述是不可见的。与开关访问一样,如果您向通常不是控件的元素(例如图像)添加点击或点击监听器,语音访问将不会将其识别为可以与之交互的元素。尽可能坚持使用 Android 的标准控件;在这种情况下,请始终使用ImageButton

本地化

Android 的本地化支持是全面和完善的,以至于开发一个可以本地化的应用可能比不可以本地化的更简单。Android Lint 还会提醒你,如果你编写的代码还没有做好本地化的准备。虽然您的应用可能只在一个地区可用,但无论如何,创建一个本地化的应用都是一种很好的做法。将来当你想修改字符串或其他资源时,这会节省你很多精力。此外,本地化选项为您的业务开拓了新的市场。即使在一个市场,你会发现比你预期的更多的人更喜欢你的应用以另一种语言提供给他们。美国人口普查局发现,近 22%的美国人,大约 7000 万人,在家里说英语以外的语言。 4

当创建一个新的应用时,Android Studio 会为你创建一个 strings.xml 文件(清单 5-14 )。作为一个好习惯,总是在这里添加用户界面中使用的任何字符串。给字符串一个名称值;这是您将在代码中用来引用您的字符串,然后将您的字符串添加到<string>标记之间。虽然本节讨论的是本地化的字符串,但是您可以用同样的方式本地化任何其他资源,包括布局、绘图、维度等等。

<resources>
      <string name="app_name">My Application</string>
      <string name="action_settings">Settings</string>
</resources>

Listing 5-14A strings.xml file as generated by Android Studio

要在应用中使用这些字符串资源,请通过您在字符串值中提供的名称来引用它们。考虑我们的action_settings字符串。我们可以在使用@string/action_settings(清单 5-15 )的布局 XML 文件中引用它,或者在使用R.string.action_settings(清单 5-16 )的代码中引用它。

val string = getString(R.string.action_settings)

Listing 5-16Accessing a string resource in code

<item
      ...
      android:title="@string/action_settings" />

Listing 5-15Accessing a string resource in a layout xml file

翻译您的应用

不要试图使用自动化服务来生成翻译。这些服务不理解你的应用的上下文,经常会给你的客户带来无意义和混乱的信息。谷歌通过 Google Play 开发者控制台提供翻译服务。虽然翻译会因应用的大小和你选择的语言而异,但谷歌建议每个应用的翻译价格通常在 50 美元左右。

在我们发送应用进行翻译之前,请花些时间注释您现有的 strings.xml 文件的内容。在字符串上方添加注释,解释字符串的使用位置及其用途。包括您对该字符串的任何限制或要求。这将有助于你的翻译为每种用法选择最合适的单词或短语。

要创建字符串的本地化版本,请选择文件➤新➤值资源文件。调用文件字符串以匹配原始字符串,并在左侧列表中选择区域设置修饰符(图 5-19 )。按添加按钮。一个新的 Android 支持的区域列表出现。选择您要本地化的区域设置-您可以在此列表中键入内容进行筛选-然后按“确定”。你会看到在项目导航器中有两个 strings.xml 文件,一个是你的原始文件,另一个是你新本地化的文件(图 5-20 )。

img/486920_1_En_5_Fig20_HTML.jpg

图 5-20

我们的项目导航器中有两个字符串文件,一个作为“tlh”本地化变体

img/486920_1_En_5_Fig19_HTML.jpg

图 5-19

创建新的本地化 strings.xml 文件

在新的字符串文件中,复制任何需要翻译的 XML 字符串条目,并将<string>标记之间的值更改为新翻译的值。您选择不在此本地化的任何字符串都将恢复为原始 strings.xml 文件的值。

键盘导航

Android 支持通过键盘或遥控器进行全面导航(图 5-21 )。事实上,某些 Android 应用,如为 Android TV 开发的应用,需要这一功能。将 USB 或蓝牙键盘连接到您的手机,除了打字,您还可以使用 tab 或箭头键在元素之间导航。Android 将使用你的应用的可访问性树来决定呈现元素的顺序,但有时需要一些提示。因此,有必要连接一个键盘,看看你的屏幕导航是否如你所愿。

img/486920_1_En_5_Fig21_HTML.jpg

图 5-21

选择驱动器时的键盘导航

检测辅助功能服务

Android 的AccessibilityManager(列表 5-17 )服务将为你提供一系列关于运行你的应用的设备的可访问性环境的信息。

val a11yManager = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager

Listing 5-17Getting the accessibility service

通过查询这个管理器,我们可以发现关于可用的可访问性服务、当前正在运行的服务以及这些服务可以为我们的客户提供什么的更多信息。为了获得所有已安装的可访问性服务的列表,我们可以请求installedAccessibilityServiceList(列表 5-18 )。

val a11yManager = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager

val installedServices = a11yManager.installedAccessibilityServiceList

Listing 5-18Getting a list of all currently installed accessibility services

运行服务

虽然已安装服务的列表会告诉我们您客户的设备能够提供什么功能,但这并不意味着这些服务中的任何一项正在使用中。可访问性管理器提供一个布尔值,告诉我们当前是否有一个或多个服务正在运行(清单 5-19 )。

val a11yManager = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager

val isAccessibilityEnabled = a11yManager.isEnabled

Listing 5-19Detecting

an accessibility service. Returns true if any service is running

现在我们知道了一个可访问性服务正在运行,我们可能想要更深入地挖掘正在运行的服务的类型。要了解我们是否需要做出改变,我们需要知道服务的功能是什么。我们可以通过查询可访问性管理器来做到这一点。没有检测对讲是否启用的直接请求,例如,您的客户可能正在使用其手机供应商的屏幕阅读器或谷歌 Play 商店的第三方屏幕阅读器。相反,我们基于服务的能力进行查询。Android 然后返回给我们一个列表,列出所有运行的具有该功能的服务。对于当前启用的可访问性服务的列表,我们可以使用AccessibilityManagergetEnabledAccessibilityServiceList方法(列表 5-20 )。我们需要传递一个常量来表示我们想要了解的服务类型。

val a11yManager = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager

val screenReaders = a11yManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN)

Listing 5-20Getting a list of all running screen readers

作为参数传递给该方法的FEEDBACK_SPOKEN常量返回任何能够提供语音反馈的服务,比如 TalkBack。我们可以向该方法传递不同的常数,以根据需要返回不同类型的服务。这些常量根据服务提供给用户的反馈类型或辅助功能服务所具有的功能来划分。要返回能够提供任何类型反馈的任何服务,请传递AccessibilityServiceInfo.FEEDBACK_ALL_MASK。要返回任何正在运行的服务,不管其功能或反馈类型如何,请传递AccessibilityServiceInfo.DEFAULT。我们将在这里讨论所有的常量值。

反馈

这些常量描述了服务如何向用户提供反馈。根据服务可以提供的反馈类型获取服务意味着服务当前正在运行。这并不一定意味着反馈类型目前已启用或处于活动状态。服务可以分为多种反馈类型。

  • FEEDBACK_ALL_MASK

    向您的客户提供任何类型的可访问性反馈的所有服务。

  • FEEDBACK_AUDIBLE

    提供听觉而非口语反馈的服务。

  • FEEDBACK_SPOKEN

    诸如 TalkBack 之类的口语服务。

  • FEEDBACK_BRAILLE

    盲文服务。

  • FEEDBACK_GENERIC

    不属于其他反馈类别的服务的总括属性。

  • FEEDBACK_HAPTIC

    提供触觉反馈的服务。

  • FEEDBACK_VISUAL

    视觉服务,如叠加、滤色器等。

能力

这些常量允许我们请求按能力分组的可访问性服务。根据服务的能力获取服务并不一定意味着这个能力当前是启用的或活动的。服务可以分为多个功能类别。

  • CAPABILITY_CAN_CONTROL_MAGNIFICATION

    可以控制屏幕缩放级别的辅助功能服务。

  • CAPABILITY_CAN_PERFORM_GESTURES

    一种能够在设备屏幕上模仿触摸手势的服务。

  • CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS

    任何可以请求过滤您的应用从 keys 收到的事件的服务。这包括设备硬件按键,如相机按钮,也包括连接的设备,如键盘和游戏手柄。

  • CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES

    辅助功能服务可以从设备的指纹传感器捕捉事件和手势。

  • CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION

    辅助功能服务,比如 TalkBack,允许用户通过点击来浏览 UI 元素,而不需要激活它们。如果正在运行,此功能还可以防止某些触摸手势被传递到您的应用。

  • CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT

    这些服务可以访问当前活动窗口中显示的应用内容。

  • DEFAULT

    如果服务没有提供其他功能,则为默认值。传递它将返回任何正在运行的服务。

摘要

  • Android 辅助功能因设备和供应商而异。额外的无障碍服务可以从谷歌 Play 商店下载。

  • 总是使用 Android 提供的 UI 元素,在需要的地方扩展它们。避免创建自己的控件,因为几乎不可能匹配标准控件的辅助功能。

  • 倾听客户的喜好,并尊重他们;不这样做可能会引起顾客的愤怒。

  • 尝试您的设备上可用的辅助功能;最坏的情况会是什么?你可能会找到对你有益的东西。

本章向我们概述了 Android 手机上可用的辅助功能和服务。我们还讨论了我们开发人员如何更好地支持它们,这些特性如何影响我们的应用,以及我们如何检测和响应客户的偏好。在下一章,我们将转移到 iOS,并开始研究 iOS 的可访问性系统是如何工作的。

Footnotes 1

https://support.google.com/accessibility/android

  2

Android 确实警告说线性扫描模式不适用于键盘,尽管我从未发现这种情况。

  3

https://developer.android.com/reference/kotlin/android/view/accessibility/CaptioningManager.CaptionStyle.html

  4

“新的美国社区调查统计数据,包括各州和当地的收入、贫困和医疗保险,”美国人口普查局,2017 年 9 月 14 日。 https://www.census.gov/newsroom/press-releases/2017/acs-single-year.html