Slide 1

Slide 1 text

Accessibility on Flutter Apps for Everyone Lara Martín @Lariki Flutter/Dart GDE - Android Miguel Beltran @MiBLT Freelance Consultant

Slide 2

Slide 2 text

Accessibility on Flutter Apps for Everyone Lara Martín @Lariki Flutter/Dart GDE - Android Miguel Beltran @MiBLT Freelance Consultant

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

TECH ASSISTIVE ADAPTIVE Two ways of helping Blue2 by Ablenet

Slide 5

Slide 5 text

https://github.com/janoodleFTW/timy-messenger

Slide 6

Slide 6 text

Types of disability (some of them) Motor Disability Vision Neurodiversity Hearing

Slide 7

Slide 7 text

Accessibility Scanner

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

iOS Simulator: Fewer accessibility options! Simulator Real device

Slide 10

Slide 10 text

Motor Disability Vision Neurodiversity Hearing

Slide 11

Slide 11 text

Motor disability Challenges • Require large click areas • Require special hardware • Require voice activated software https://webaim.org/articles/motor/motordisabilities

Slide 12

Slide 12 text

Motor disability Challenges • Require large click areas • Require special hardware • Require voice activated software How to help • Games: Difficulty settings, turns • Keyboard navigation • Voice navigation • Adaptive UI components • Autocompletion https://webaim.org/articles/motor/motordisabilities

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

https://support.google.com/accessibility/android/answer/6122836?hl=en

Slide 16

Slide 16 text

Switch Access 1. Open user profile 2. Navigate back to chat window 3. Start creating a message

Slide 17

Slide 17 text

Found Issues Small touch targets Switch navigation worked well on start, but keyboard navigation was bad.

Slide 18

Slide 18 text

Motor Disability Vision Neurodiversity Hearing

Slide 19

Slide 19 text

Vision 4 levels of visual function • Blindness • Severe visual impairment • Moderate visual impairment • Mild vision https://www.who.int/news-room/fact-sheets/detail/blindness-and-visual-impairment

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Font Scaling • Make text larger • Supported by the Text widget • But not with RichText

Slide 22

Slide 22 text

Default Largest Font Scaling (Android)

Slide 23

Slide 23 text

Font Scaling (iOS)

Slide 24

Slide 24 text

Display Size (Android) • Make items larger • Not text, but UI components

Slide 25

Slide 25 text

Display Size (Android) Default Largest

Slide 26

Slide 26 text

Bold Text (iOS)

Slide 27

Slide 27 text

Magnify • Both on Android and iOS • Tab X times to zoom • Drag with X fingers

Slide 28

Slide 28 text

iOS: Unsupported Options? • Button Shapes (underline) • On/Off Labels • Reduce Transparency • Increase Contrast These show no difference. Should we check the flutter source code and verify if they are supported?

Slide 29

Slide 29 text

Colorblindness Challenges • Not being able to see or differentiate certain colours • Affects 8% of male population, 0.5% women Find links for picking colours

Slide 30

Slide 30 text

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 Find links for picking colours

Slide 31

Slide 31 text

Simulate Color Space (Android) Check if iOS has it

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

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” Add how to add Talkback (Google Play store app)?

Slide 35

Slide 35 text

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”

Slide 36

Slide 36 text

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”

Slide 37

Slide 37 text

Found Issues TalkBack: Missing labels TalkBack: Missing text descriptions like author of a message Low text contrast Display size not supported Unsupported iOS features Unsupported iOS features?

Slide 38

Slide 38 text

Motor Disability Vision Neurodiversity Hearing

Slide 39

Slide 39 text

Neurodiversity Challenges • Focusing problems • Learning difficulties • Autism • Dyslexia • ADHD

Slide 40

Slide 40 text

Neurodiversity Challenges • Focusing problems • Learning difficulties • Autism • Dyslexia • ADHD How to help • Minimal design • Voice narration and subtitles • Spell checking • Remember settings and passwords • Guide the user (without overwhelm)

Slide 41

Slide 41 text

Helping neurodiverse users: • Autocorrection is enabled • Capitalization by sentences not! We can help users write better by enabling Text Capitalization by sentences. Este slide debería ser el assessment de la app en cuanto a los problemas de accesibilidad. Decir si por defecto

Slide 42

Slide 42 text

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.

Slide 43

Slide 43 text

Found Issues Sentence Capitalization

Slide 44

Slide 44 text

Motor Disability Vision Neurodiversity Hearing

Slide 45

Slide 45 text

Hearing Challenges • High hearing threshold by air or bone conduction. • Failure to repeat words in a word recognition test. https://www.alllaw.com/articles/nolo/disability/determination-deafness-hearing-loss.html

Slide 46

Slide 46 text

Hearing Challenges • High hearing threshold by air or bone conduction. • Failure to repeat words in a word recognition test. How to help • Closed captioning • Games: Visual signals • Vibrate on notifications https://www.alllaw.com/articles/nolo/disability/determination-deafness-hearing-loss.html

Slide 47

Slide 47 text

Live Captioning - Android 10 feature - Detects speech - Displays subtitles on screen - Be sure that your app works with it!

Slide 48

Slide 48 text

Found Issues Nothing to fix

Slide 49

Slide 49 text

Let’s Fix It

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

Touch Targets

Slide 52

Slide 52 text

Touch Target User Name InkWell( //... child: Text(author.name) ) InkWell is constrained to the child region. Not satisfying the “Minimum Interactive Dimension”

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

Touch Target with ConstrainedBox InkWell( //... child: ConstrainedBox( constraints: const BoxConstraints( minWidth: kMinInteractiveDimension, minHeight: kMinInteractiveDimension, ), child: Text(author.name) ) )

Slide 55

Slide 55 text

Fix Alignment in ConstrainedBox InkWell( //... child: ConstrainedBox( constraints: .. child: Align( alignment: Alignment.centerLeft, child: Text(author.name) ) ) )

Slide 56

Slide 56 text

Capitalization and Auto-Correct

Slide 57

Slide 57 text

TextField( textCapitalization: TextCapitalization.sentences, ) Fix text capitalisation: • Disabled by default (none) • Quick win! • Think of the use case.

Slide 58

Slide 58 text

TextField( enableSuggestions: true, autocorrect: true, ) More improvements for Neurodiverse users: • Autocorrection • Enable Suggestions Both are enabled by default.

Slide 59

Slide 59 text

Low Contrast

Slide 60

Slide 60 text

Low Contrast InputDecoration( hintStyle: AppTheme.inputHintTextStyle, ), Color.fromRGBO(153, 153, 153, 1.0);

Slide 61

Slide 61 text

Default Hint Color input_decorator.dart ThemeData.disabledColor Colors.black38 = Color(0x61000000);

Slide 62

Slide 62 text

Default Hint vs. Custom Default Custom

Slide 63

Slide 63 text

MediaQuery HighContrast “Whether the user requested a high contrast between foreground and background content on iOS, via Settings -> Accessibility -> Increase Contrast.” It is always false* https://api.flutter.dev/flutter/widgets/MediaQueryData/highContrast.html MediaQuery.of(context).highContrast * https://github.com/flutter/flutter/issues/48418

Slide 64

Slide 64 text

Text Scaling

Slide 65

Slide 65 text

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: … )

Slide 66

Slide 66 text

Semantic Labels

Slide 67

Slide 67 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?

Slide 68

Slide 68 text

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… )

Slide 69

Slide 69 text

Fixing the Menu Button • Wrap with a Semantic Widget • Add a label “Menu” • Set Button to True Semantics( label: “Menu", button: true, child: MenuWidget(…) )

Slide 70

Slide 70 text

Fixing the Send Button • Add “enabled” status to Semantics Semantics( label: “Send", button: true, enabled: _enabled, child: SendWidget(…) ) Disabled Enabled • TalkBack says “Send button disabled”

Slide 71

Slide 71 text

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”

Slide 72

Slide 72 text

Fixing Messages Semantics( label: "Message from ${_author.name} ${_message.body} " "at ${DateFormat.Hm().format(_message.timestamp)}", child: MessageWidget(…) ) Speaker notes is confusing?

Slide 73

Slide 73 text

Fixing Messages ExcludeSemantics( child: RichText( … ) ) ExcludeSemantics to remove Text Widgets from Semantics tree

Slide 74

Slide 74 text

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!

Slide 75

Slide 75 text

We are done!

Slide 76

Slide 76 text

TODO DONE 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

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

No content