Implémentation de l'accessibilité Flutter
Sommaire
Gérer la sémantique
Appuyez-vous sur les widgets standard de Flutter (par exemple TabBar, MenuAnchor) pour l'attribution automatique des rôles sémantiques chaque fois que possible. Lors de la création de composants personnalisés ou de la modification des comportements par défaut, définissez explicitement le rôle du composant UI à l'aide du widget Semantics.
- Enveloppez les composants UI personnalisés dans un widget
Semantics. - Attribuez la valeur enum
SemanticsRoleappropriée à la propriétérolepour définir le rôle de l'élément (par exemple, button, list, heading). - Si vous ciblez Flutter Web, notez que Flutter traduit ces rôles en rôles ARIA correspondants dans le DOM HTML.
- Activez explicitement l'accessibilité web. Elle est désactivée par défaut pour des raisons de performance. Demandez à vos utilisateurs d'appuyer sur le bouton invisible
aria-label="Enable accessibility", ou forcez-la programmatiquement dans votre fonctionmain().
Auditer l'accessibilité
Mettez en œuvre les workflows suivants pour vérifier que votre application respecte les normes d'accessibilité.
Progression des tâches : analyse spécifique à la plateforme
Copiez cette checklist pour suivre votre progression d'audit manuel sur les plateformes cibles :
- [ ] Si vous testez sur Android :
- Installez Accessibility Scanner depuis Google Play.
- Activez-le via Paramètres > Accessibilité > Accessibility Scanner > Activé.
- Appuyez sur l'icône de coche d'Accessibility Scanner au-dessus de votre application en cours d'exécution pour lancer l'analyse.
- [ ] Si vous testez sur iOS :
- Ouvrez le dossier
iosdans Xcode et exécutez l'application sur un simulateur. - Accédez à Xcode > Open Developer Tools > Accessibility Inspector.
- Sélectionnez Inspection > Enable Point to Inspect et cliquez sur les éléments UI pour vérifier les attributs.
- Sélectionnez Audit > Run Audit pour générer un rapport de problèmes.
- Ouvrez le dossier
- [ ] Si vous testez sur Web :
- Ouvrez Chrome DevTools.
- Inspectez l'arbre HTML sous le nœud
semantics host. - Accédez à l'onglet Elements et ouvrez le sous-onglet Accessibility pour inspecter les données ARIA exportées.
- Visualisez les nœuds sémantiques en exécutant l'application avec :
flutter run -d chrome --profile --dart-define=FLUTTER_WEB_DEBUG_SHOW_SEMANTICS=true.
Progression des tâches : tests automatisés
Intégrez l'API Accessibility Guideline de Flutter dans vos tests de widgets pour détecter automatiquement les problèmes de contraste, de taille de cible et d'étiquetage.
- [ ] Créez un fichier de test dédié (par exemple,
test/a11y_test.dart). - [ ] Initialisez la poignée sémantique en utilisant
tester.ensureSemantics(). - [ ] Assertez avec
androidTapTargetGuideline(minimum 48x48px). - [ ] Assertez avec
iOSTapTargetGuideline(minimum 44x44px). - [ ] Assertez avec
labeledTapTargetGuideline. - [ ] Assertez avec
textContrastGuideline(minimum 3:1 pour le texte grand). - [ ] Libérez la poignée sémantique à la fin du test.
Déboguer l'arbre sémantique
Quand les nœuds sémantiques sont mal placés ou manquants, exécutez la boucle de rétroaction suivante pour identifier et résoudre les divergences.
- Exécutez le validateur : déclenchez un dump de l'arbre Semantics dans la console.
- Activez l'accessibilité via un outil système ou
SemanticsDebugger. - Invoquez
debugDumpSemanticsTree()(par exemple, liez-le au callbackonTapd'unGestureDetectorpour un déclenchement facile lors du débogage).
- Activez l'accessibilité via un outil système ou
- Examinez les erreurs : analysez la sortie de la console pour localiser les étiquettes manquantes, les rôles incorrects ou les nœuds sémantiques mal imbriqués.
- Corrigez : enveloppez les widgets problématiques dans des widgets
SemanticsouMergeSemantics, appliquez leSemanticsRolecorrect et répétez l'étape 1 jusqu'à ce que l'arbre reflète exactement l'interface utilisateur visuelle.
Exemples
Activation programmatique de l'accessibilité Web
Forcez l'arbre Semantics à se construire immédiatement sur Flutter Web.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';
void main() {
runApp(const MyApp());
if (kIsWeb) {
SemanticsBinding.instance.ensureSemantics();
}
}
Définition explicite des rôles sémantiques
Attribuez des rôles list et list-item explicites à une mise en page personnalisée.
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) {
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.'),
),
),
],
),
);
}
}
Tests d'accessibilité automatisés
Implémentez l'API Accessibility Guideline dans un test de widget.
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());
// Check tap target sizes
await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
await expectLater(tester, meetsGuideline(iOSTapTargetGuideline));
// Check labels and contrast
await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
await expectLater(tester, meetsGuideline(textContrastGuideline));
handle.dispose();
});
}