Logo
Section 1 / 5

Flutter 中的可访问性

学习如何让你的 Flutter 应用更具可访问性。

导入

Flutter 中的可访问性

学习如何让你的 Flutter 应用更具可访问性。

可访问性 指的是让我们的应用程序尽可能被更多人使用。我们通常认为可访问性是针对残障人士的,但实际上,使应用程序具备可访问性也对其他群体有益,例如使用不同语言的人、从右向左阅读的人、网络连接较慢的人,或有轻微功能障碍的人。

我们不应排除任何能力、处境或文化背景的人使用或有效使用我们的应用程序。

在本课程中,我们将学习如何让应用程序对不同用户群体更具可访问性,无论他们的能力或处境如何。

我们将通过以下方式实现这一目标:

  1. 了解不同类型的残疾
  2. 使用工具扫描应用程序以发现可访问性问题
  3. 为应用程序的语义添加标签
  4. 让应用程序对神经多样性用户更加友好

残疾类型

有残疾的人和没有残疾的人一样多样化,他们的能力也各不相同。残疾主要分为四类:

  • 运动障碍:影响运动能力
  • 视觉障碍:影响视觉能力
  • 神经多样性障碍:影响感知和专注力
  • 听觉障碍

下表列出了不同类型的残疾、人们在使用我们的应用程序时可能遇到的挑战,以及我们可以通过提升应用可访问性来帮助他们的方式。

残疾类型面临的挑战如何帮助
运动障碍需要更大的点击/触摸区域;需要特殊硬件;需要语音控制软件在游戏中提供不同难度等级;支持键盘导航;支持语音导航;使用自适应 UI 组件;启用文本自动补全
视觉障碍失明;严重视力受损;中度视力受损;轻度视力受损;色盲使用大字号;支持屏幕阅读器;高对比度内容;同时使用颜色和图标传递信息;在应用中提供颜色调整选项
神经多样性障碍注意力难以集中;学习困难;自闭症;阅读障碍;注意力缺陷多动障碍(ADHD)采用极简设计;提供语音朗读和字幕;支持拼写检查、自动纠正和句子首字母大写;允许保存设置和密码;通过提示引导用户,但不过度干扰
听觉障碍空气传导或骨传导听力阈值较高;词语识别测试中无法重复单词提供字幕;在游戏内加入视觉信号;通知时使用震动

No configuration found for ID: b67d07182bacc1116c071e5c148f5258f0b4b45c8c8ddbeae2cf901f3647b108

使用可访问性扫描工具检测应用问题

为了发现应用程序中的可访问性问题,请在 Android 模拟器或实体设备上运行应用,并使用 可访问性扫描工具 Android 应用。

上述示例应用包含多个可访问性问题,如下图所示。

...
1 / 6

发现的所有可访问性问题

请按照以下步骤修复可访问性扫描工具识别出的问题:

  1. 在 home_page.dart 文件中,找到 // TODO-1: 为 Scaffold 添加语义标签(第 36 行)。将整个 Scaffold 包裹在 Semantics 小部件中,并为其添加标签,代码如下:

    1 2Widget build(BuildContext context) { 3 return Semantics( 4 label: "主页", 5 child: Scaffold( 6 ... 7 ), 8 ); 9}

    上述更改将使屏幕阅读器能够为视障及其他障碍用户朗读“主页”标签。

  2. 在 home_page.dart 文件中,找到 // TODO-2: 提高文字与背景的对比度。为了使 TextField 的 hintText 更清晰可见,将提示文字颜色改为更深的灰色,以增强与背景的对比。替换原代码如下:

    1hintStyle: TextStyle(color: Colors.grey[600]),
  3. 为解决最后一个问题,进入 message_widget.dart 文件的第 35 行,将 InkWell 替换为以下代码:

    1InkWell( 2 child: ConstrainedBox( 3 constraints: const BoxConstraints( 4 minHeight: kMinInteractiveDimension, 5 minWidth: kMinInteractiveDimension, 6 ), 7 child: Align( 8 alignment: Alignment.centerLeft, 9 // TODO-9: 为消息正文文本排除语义 10 child: Text( 11 message['author']!, 12 style: const TextStyle(fontWeight: FontWeight.bold), 13 ), 14 ), 15 ), 16 onTap: () { 17 Navigator.of(context).push(MaterialPageRoute( 18 builder: (_) => 19 AuthorPage(author: message['author']!))); 20 }, 21),

    由于 InkWell 的点击区域与其子组件大小一致,上述代码通过使用 ConstrainedBox 定义一个更大的容器包裹 Text 组件,从而扩大了点击区域,使文本更易于点击。

为应用程序标注语义信息

为了发现并可视化应用程序中各组件的语义信息,可以将某个组件包裹在 SemanticsDebugger 中。将 HomePage 的 Scaffold 包裹在 SemanticsDebugger 中后,将得到如下图像:

...
语义调试器输出

上述标记的区域是屏幕上需要添加语义标签的部分,以便屏幕阅读器帮助残障用户识别界面组件。请按以下步骤为这些组件添加语义标签:

  1. 在 home_page.dart 文件中,将 // TODO-4: 为菜单图标添加语义标签 替换为以下代码:

    1semanticLabel: "菜单",
  2. 将 // TODO-5: 为“附加媒体”图标添加语义标签 替换为:

    1semanticLabel: "附加媒体",
  3. 将 // TODO-6: 为“发送”按钮添加语义标签 替换为:

    1semanticLabel: "发送",

    第 1、2、3 步分别为“菜单”、“附加媒体”和“发送”图标添加了语义标签,使屏幕阅读器能将其读作“菜单按钮”、“附加媒体按钮”和“发送按钮”。

    注意:由于“菜单”按钮处于禁用状态,屏幕阅读器会读作“菜单按钮已禁用”。

    接下来,进入 message_widget.dart 文件,完成第 4 至第 8 步。

  4. 在 message_widget.dart 文件中,找到 // TODO-7: 为 MessageWidget 添加语义标签,并将 Padding 组件包裹在 Semantics 小部件中。修改后的代码如下:

    1return Semantics( 2 label: "来自 ${message['author']} 的消息:${message['body']},时间:${DateFormat.Hm().format(DateTime.parse(message['time']!))}。", 3 child: Padding( 4 ... 5 ), 6);

    上述代码为整个消息组件添加了语义标签,朗读内容包括发信人姓名、消息内容和发送时间。

  5. 找到 // TODO-8: 为作者头像文本排除语义,将 Text 组件替换为以下代码:

    1ExcludeSemantics(child: Text(message['author']!.substring(0, 1))),
  6. 找到 // TODO-9: 为消息正文文本排除语义,将作者名称的 Text 组件替换为以下代码:

    1ExcludeSemantics( 2 child: Text( 3 message['author']!, 4 style: const TextStyle(fontWeight: FontWeight.bold), 5 ), 6),
  7. 找到 // TODO-10: 为消息时间文本排除语义,将时间戳 Text 组件替换为以下代码:

    1ExcludeSemantics( 2 child: Text( 3 DateFormat.Hm().format(DateTime.parse(message['time']!)), 4 style: Theme.of(context).textTheme.caption, 5 ), 6),
  8. 找到 // TODO-11: 为消息正文文本排除语义,将消息内容的 Text 组件替换为:

    1ExcludeSemantics(child: Text(message['body']!)),

    第 5 至第 8 步使用 ExcludeSemantics 小部件排除了作者、消息和时间戳 Text 组件的语义。之所以这样做,是因为我们在第 4 步已经通过整体 MessageWidget 的语义标签概括了全部信息,因此无需重复朗读这些文本内容。

    屏幕阅读器默认会朗读 Text 组件的内容。如果不排除这些组件的语义,屏幕阅读器会重复朗读内容,造成冗余。

    为测试语义功能,可下载并在启用了 TalkBack 功能的 Android 设备或模拟器上运行应用。iOS 也支持通过 VoiceOver 功能实现屏幕朗读。

让应用对神经多样性用户更友好

为了让神经多样性用户在使用应用时体验更舒适,可以在适用场景中启用自动建议、自动补全和自动首字母大写功能。

在 home_page.dart 文件中,找到 // TODO-12: 让应用对神经多样性用户更友好,并替换为以下属性添加到 TextField 中:

1autocorrect: true, 2enableSuggestions: true, 3textCapitalization: TextCapitalization.sentences,

启用这些属性后,神经多样性用户在撰写消息时将获得所需的支持。

No configuration found for ID: 9d96fa551930d4d42fc759ea6bec34a72a9b312dfc91c582c9ae4f11522b9c3a

导航与路由

Flutter 中的国际化