確保應用程式能夠被廣泛的使用者群體訪問是構建高質量應用程式的重要組成部分。設計不佳的應用程式會給所有年齡段的人造成障礙。《聯合國殘疾人權利公約》規定了確保資訊系統普遍可訪問性的道德和法律義務;世界各國都強制將無障礙功能作為一項要求;公司也認識到最大化其服務可訪問性的商業優勢。

我們強烈建議您在釋出應用程式之前,將無障礙功能檢查清單作為關鍵標準。Flutter 致力於支援開發者使其應用程式更具可訪問性,除了底層作業系統提供的支援外,還包括對無障礙功能的一流框架支援,包括:

大字型
以使用者指定的字型大小渲染文字元件
螢幕閱讀器
傳達關於 UI 內容的語音反饋
足夠的對比度
以具有足夠對比度的顏色渲染元件

這些功能的詳細資訊將在下面討論。

檢查無障礙支援

#

除了測試這些特定主題外,我們還建議使用自動化無障礙掃描器

  • 對於 Android

    1. 安裝適用於 Android 的無障礙掃描器
    2. Android 設定 > 無障礙功能 > 無障礙掃描器 > 開啟中啟用無障礙掃描器
    3. 導航到無障礙掃描器“複選框”圖示按鈕以啟動掃描
  • 對於 iOS

    1. 在 Xcode 中開啟 Flutter 應用程式的iOS資料夾
    2. 選擇模擬器作為目標,然後點選執行按鈕
    3. 在 Xcode 中,選擇Xcode > 開啟開發者工具 > 無障礙檢查器
    4. 在無障礙檢查器中,選擇檢查 > 啟用指向檢查,然後選擇正在執行的 Flutter 應用程式中的各種使用者介面元素,以檢查其無障礙屬性
    5. 在無障礙檢查器中,選擇工具欄中的審計,然後選擇執行審計以獲取潛在問題的報告
  • 對於 Web

    1. 開啟 Chrome DevTools(或其他瀏覽器中的類似工具)
    2. 檢查包含 Flutter 生成的 ARIA 屬性的 HTML 樹。
    3. 在 Chrome 中,“Elements”選項卡有一個“Accessibility”子選項卡,可用於檢查匯出到語義樹的資料

大字型

#

Android 和 iOS 都包含用於配置應用程式所需字型大小的系統設定。Flutter 文字元件在確定字型大小時會遵循此作業系統設定。

字型大小由 Flutter 根據作業系統設定自動計算。但是,作為開發者,您應該確保您的佈局有足夠的空間在字型大小增加時渲染其所有內容。例如,您可以在配置為使用最大字型設定的小螢幕裝置上測試應用程式的所有部分。

示例

#

以下兩個截圖顯示了使用預設 iOS 字型設定和在 iOS 無障礙設定中選擇最大字型設定時渲染的標準 Flutter 應用程式模板。

Default font setting
預設字型設定
Largest accessibility font setting
最大無障礙字型設定

螢幕閱讀器

#

對於移動裝置,螢幕閱讀器(TalkBackVoiceOver)使視障使用者能夠獲得關於螢幕內容的語音反饋,並透過移動裝置上的手勢和桌面上的鍵盤快捷鍵與 UI 互動。在您的移動裝置上開啟 VoiceOver 或 TalkBack,並在您的應用程式中導航。

要開啟裝置上的螢幕閱讀器,請完成以下步驟

  1. 在您的裝置上,開啟設定
  2. 選擇無障礙功能,然後選擇TalkBack
  3. 開啟或關閉“使用 TalkBack”。
  4. 選擇確定。

要了解如何查詢和自定義 Android 的無障礙功能,請觀看以下影片。

在新標籤頁中觀看 YouTube 影片:“自定義 Pixel 和 Android 無障礙功能”

  1. 在您的裝置上,開啟設定 > 無障礙功能 > VoiceOver
  2. 開啟或關閉 VoiceOver 設定

要了解如何查詢和自定義 iOS 無障礙功能,請觀看以下影片。

在新標籤頁中觀看 YouTube 影片:“如何使用 VoiceOver 導航您的 iPhone 或 iPad”

對於 Web,目前支援以下螢幕閱讀器

移動瀏覽器

  • iOS - VoiceOver
  • Android - TalkBack

桌面瀏覽器

  • macOS - VoiceOver
  • Windows - JAWs & NVDA

Web 端螢幕閱讀器使用者必須切換“啟用無障礙功能”按鈕來構建語義樹。如果您使用此 API 以程式設計方式為您的應用程式自動啟用無障礙功能,則使用者可以跳過此步驟

dart
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';

void main() {
  runApp(const MyApp());
  SemanticsBinding.instance.ensureSemantics();
}

Windows 自帶一個名為 Narrator 的螢幕閱讀器,但一些開發者推薦使用更流行的 NVDA 螢幕閱讀器。要了解如何使用 NVDA 測試 Windows 應用程式,請檢視面向前端開發人員的螢幕閱讀器 101 (Windows)

在 Mac 上,您可以使用 macOS 中包含的 VoiceOver 桌面版。

在新標籤頁中觀看 YouTube 影片:“螢幕閱讀器基礎知識:VoiceOver”

在 Linux 上,一個流行的螢幕閱讀器名為 Orca。它隨某些發行版預裝,並可在apt等包儲存庫中獲得。要了解如何使用 Orca,請檢視在 Gnome 桌面中使用 Orca 螢幕閱讀器入門


觀看以下影片演示,瞭解 Victor Tsaran 如何使用 VoiceOver 與現已存檔的Flutter Gallery Web 應用程式。

Flutter 的標準組件會自動生成一個無障礙樹。但是,如果您的應用程式需要不同的東西,可以使用Semantics元件進行自定義。

當您的應用程式中有需要特定語音朗讀的文字時,透過呼叫TextSpan.locale告知螢幕閱讀器使用哪種語音。請注意,MaterialApp.localeLocalizations.override不會影響螢幕閱讀器使用的語音。通常,螢幕閱讀器會使用系統語音,除非您使用TextSpan.locale明確設定。

足夠的對比度

#

足夠的顏色對比度使文字和影像更易於閱讀。除了使有各種視力障礙的使用者受益外,足夠的顏色對比度還有助於所有使用者在極端光照條件下(例如在陽光直射下或在低亮度顯示器上)檢視介面。

W3C 建議

  • 小文字(常規 18 磅以下或粗體 14 磅以下)至少 4.5:1
  • 大文字(常規 18 磅及以上或粗體 14 磅及以上)至少 3.0:1

在構建時考慮無障礙功能

#

確保您的應用程式能夠被所有人使用意味著從一開始就將無障礙功能融入其中。對於某些應用程式來說,這說起來容易做起來難。在下面的影片中,我們的兩位工程師將一個無障礙功能糟糕的移動應用程式變成了一個利用 Flutter 內建元件提供顯著更具無障礙性的體驗的應用程式。

在新標籤頁中觀看 YouTube 影片:“構建考慮無障礙功能的 Flutter 應用程式”

透過語義角色增強無障礙功能

#

什麼是語義角色?

#

語義角色定義了 UI 元素的用途,幫助螢幕閱讀器和其他輔助工具有效地解釋和呈現您的應用程式給使用者。例如,一個角色可以指示一個元件是按鈕、連結、標題、滑塊,還是表格的一部分。

雖然 Flutter 的標準組件通常會自動提供這些語義,但一個沒有明確定義角色的自定義元件對於螢幕閱讀器使用者來說可能是無法理解的。

透過分配適當的角色,您可以確保

  • 螢幕閱讀器可以正確地宣佈元素的型別和用途。
  • 使用者可以使用輔助技術更有效地導航您的應用程式。
  • 您的應用程式符合 Web 無障礙標準,提高了可用性。

在 Flutter for web 中使用SemanticsRole

#

Flutter 提供了帶有SemanticsRole列舉Semantics元件,允許開發者為其元件分配特定的角色。當您的 Flutter web 應用程式渲染時,這些 Flutter 特定的角色會轉換為網頁 HTML 結構中相應的 ARIA 角色。

1. 來自標準組件的自動語義

許多標準 Flutter 元件,如TabBarMenuAnchorTable,會自動包含語義資訊及其角色。只要可能,優先使用這些標準組件,因為它們開箱即用地處理了許多無障礙方面的問題。

2. 顯式新增或覆蓋角色

對於自定義元件或當預設語義不足時,使用Semantics元件定義角色

這是一個如何顯式定義列表及其項的示例

dart
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';


class MyCustomListWidget extends StatelessWidget {
  const MyCustomListWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // This example shows how to explicitly assign list and listitem roles
    // when building a custom list structure. 
    return Semantics(
      role: SemanticsRole.list,
      explicitChildNodes: true,
      child: Column( 
        children: <Widget>[
          Semantics(
            role: SemanticsRole.listItem, 
            child: const Padding(
              padding: EdgeInsets.all(8.0),
              child: Text('Content of the first custom list item.'),
            ),
          ),
          Semantics(
            role: SemanticsRole.listItem, 
            child: const Padding(
              padding: EdgeInsets.all(8.0),
              child: Text('Content of the second custom list item.'),
            ),
          ),
        ],
      ),
    );
  }
}

在移動裝置上測試無障礙功能

#

使用 Flutter 的無障礙指南 API測試您的應用程式。此 API 檢查您的應用程式 UI 是否符合 Flutter 的無障礙建議。這些建議涵蓋了文字對比度、目標大小和目標標籤。

以下程式碼片段顯示瞭如何在名為AccessibleApp的示例元件上使用指南 API

test/a11y_test.dart
dart
import 'package:flutter_test/flutter_test.dart';
import 'package:your_accessible_app/main.dart';

void main() {
  testWidgets('Follows a11y guidelines', (tester) async {
    final SemanticsHandle handle = tester.ensureSemantics();
    await tester.pumpWidget(const AccessibleApp());

    // Checks that tappable nodes have a minimum size of 48 by 48 pixels
    // for Android.
    await expectLater(tester, meetsGuideline(androidTapTargetGuideline));

    // Checks that tappable nodes have a minimum size of 44 by 44 pixels
    // for iOS.
    await expectLater(tester, meetsGuideline(iOSTapTargetGuideline));

    // Checks that touch targets with a tap or long press action are labeled.
    await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));

    // Checks whether semantic nodes meet the minimum text contrast levels.
    // The recommended text contrast is 3:1 for larger text
    // (18 point and above regular).
    await expectLater(tester, meetsGuideline(textContrastGuideline));
    handle.dispose();
  });
}

要嘗試這些測試,請在您在編寫您的第一個 Flutter 應用程式程式碼實驗室中建立的應用程式上執行它們。該應用程式主螢幕上的每個按鈕都作為一個可點選的目標,文字以 18 磅字型渲染。

您可以將指南 API 測試與其他元件測試一起新增,或者在單獨的檔案中新增,例如此示例中的test/a11y_test.dart

在 Web 端測試無障礙功能

#

您可以使用以下命令列標誌在 profile 和 release 模式下透過視覺化為您的 Web 應用程式建立的語義節點來除錯無障礙功能

flutter run -d chrome --profile --dart-define=FLUTTER_WEB_DEBUG_SHOW_SEMANTICS=true

啟用該標誌後,語義節點會顯示在元件上方;您可以驗證語義元素是否放置在應有的位置。如果語義節點放置不正確,請提交錯誤報告

無障礙功能釋出清單

#

以下是您在準備釋出應用程式時需要考慮的一些非詳盡列表。

  • 主動互動。確保所有主動互動都能做些事情。任何可以按下的按鈕在按下時都應該做些事情。例如,如果您為onPressed事件設定了一個無操作回撥,請將其更改為在螢幕上顯示一個SnackBar,解釋您剛剛按下了哪個控制元件。
  • 螢幕閱讀器測試。當您點選頁面上的所有控制元件時,螢幕閱讀器應該能夠描述它們,並且描述應該清晰易懂。使用TalkBack (Android) 和VoiceOver (iOS) 測試您的應用程式。
  • 對比度。我們鼓勵您在控制元件或文字與背景之間保持至少 4.5:1 的對比度,停用元件除外。影像也應該經過檢查以確保足夠的對比度。
  • 上下文切換。在輸入資訊時,不應有任何東西自動改變使用者的上下文。通常,元件應避免在沒有某種確認操作的情況下改變使用者的上下文。
  • 可點選目標。所有可點選目標都應至少為 48x48 畫素。
  • 錯誤。重要的操作應該能夠撤銷。在顯示錯誤的欄位中,如果可能,建議進行更正。
  • 色覺缺陷測試。控制元件在色盲和灰度模式下應可用和可讀。
  • 縮放因子。UI 在文字大小和顯示縮放的非常大縮放因子下應保持可讀和可用。

瞭解更多

#

要了解更多關於 Flutter 和無障礙功能的資訊,請檢視社群成員撰寫的以下文章