Accessibility on Flutter Apps for Everyone Lara Martín @Lariki Flutter/Dart GDE - Android Miguel Beltran @MiBLT Freelance Consultant Updated: August 2020
What’s accessibility? Design of products to be used by people with disabilities. Universal design Products that can be used by the widest majority of people. https://unsplash.com/@yomex4life
Motor disability Challenges • Require large click areas • Require special hardware • Require voice activated software https://webaim.org/articles/motor/motordisabilities
Keyboard Navigation - We try to open the user profile and navigate through the app but it doesn’t work well - “Selected” color hard to see most of the time
Vision 4 levels of visual function • Blindness • Severe visual impairment • Moderate visual impairment • Mild vision How to help • Large font sizes • Screen readers • High contrast content https://www.who.int/news-room/fact-sheets/detail/blindness-and-visual-impairment
Colorblindness Challenges • Not being able to see or differentiate certain colours • Affects 8% of male population, 0.5% women How to help • Use color AND icons to convey messages • Options to change color
Android: TalkBack - Tap on screen reads Scaffold title. - Menu buttons are unlabelled - Attach button is unlabelled - Tap on message item reads the time + message but not the username - “Dogs are the best” - “Unlabelled button” - “16:18 - Good morning everyone! smiley face”
Android: TalkBack + Gestures - Swipe to navigate to next item. - TalkBar reads the item. - “Dogs are the best” - “Unlabelled button” - “16:18 - Good morning everyone! smiley face”
iOS: VoiceOver + Gestures - Swipe to navigate to next item. - VoiceOver reads the item. - Different reads than Android - “Dogs are the best” - “Image - Puzzles” - “Image - Possibly Menu” - “16:18 - Good morning everyone! smiley face”
Found Issues TalkBack: Missing labels TalkBack: Missing text descriptions like author of a message Low text contrast Display size not supported Unsupported iOS features
Helping neurodiverse users: • Autocorrection is enabled • Capitalization by sentences not! We can help users write better by enabling Text Capitalization by sentences.
Helping neurodiverse users: • Offer text narration • Users can read and listen at the same time • Helps distracted minds We can help users with learning difficulties.
TODO LIST Fix touch targets for names and user avatars Fix sentence capitalisation Fix low text contrast Check dynamic font scaling with textScaleFactor Fix missing semantic labels on buttons Fix missing semantic text descriptions like author of a message
Touch Target User Name InkWell( //... child: Text(author.name) ) InkWell is constrained to the child region. Not satisfying the “Minimum Interactive Dimension”
kMinInteractiveDimension “The minimum dimension of any interactive region according to Material guidelines.” 48.0 Android 44.0 iOS (kMinInteractiveDimensionCupertino) https://api.flutter.dev/flutter/material/kMinInteractiveDimension-constant.html
TextField( textCapitalization: TextCapitalization.sentences, ) Fix text capitalisation: • Disabled by default (none) • Quick win! • Think of the use case.
TextField( enableSuggestions: true, autocorrect: true, ) More improvements for Neurodiverse users: • Autocorrection • Enable Suggestions Both are enabled by default.
MediaQuery HighContrast “Whether the user requested a high contrast between foreground and background content on iOS, via Settings -> Accessibility -> Increase Contrast.” MediaQuery.of(context).highContrast
RichText and textScaleFactor RichText allows you to have text spans to do things like (highlight URLs). Does not support text scaling by default! RichText( textScaleFactor: MediaQuery.of(context).textScaleFactor, text: … )
Missing Labels We need to add descriptions to Widgets! Semantics Widget • Explains what a piece of UI means. • It is enabled? • It is a button? • It is read only?
SemanticsDebugger • Draws each Semantics region • Displays the TalkBack text • Will help us fix the app! Add to the top of your Widget tree SemanticsDebugger( child: …Scaffold or similar… )
Fixing the Menu Button • Wrap with a Semantic Widget • Add a label “Menu” • Set Button to True Semantics( label: “Menu", button: true, child: MenuWidget(…) )
Scaffold Semantics • Tap on the center reads AppBar title “Dogs are the best” • Wrap Scaffold with Semantics Semantics( label: "Chat Screen", child: Scaffold( … ) ) • Now reads “Chat Screen - Dogs are the best”
testWidgets(… { await tester.pumpWidget(CirclesApp()); expect(find.bySemanticsLabel("Menu"), findsOneWidget); }); Testing Semantics • Use bySemanticsLabel to find Widgets when testing • Easier to use than other Matchers! • And you help others!
TODO DONE LIST Fix touch targets for names and user avatars Fix sentence capitalisation Fix low text contrast (iOS) Check dynamic font scaling with textScaleFactor Fix missing semantic labels on buttons Fix missing semantic text descriptions like author of a message
Summary Perform analysis with Accessibility Scanner on Android Test large scale fonts on iOS (larger setting) Use Semantics as alternative for Widget Tests for a win-win Embrace TextField features like capitalization
Thank You! L a r a M a r t í n F l u t t e r G D E A n d r o i d D e v e l o p e r @ L a r i k i M i g u e l B e l t r a n F r e e l a n c e C o n s u l t a n t @ M i B LT