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
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?
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
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.
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