Accessibility Guide
This guide explains how to use the accessibility features in the Flutter Riverpod Clean Architecture template to make your app more inclusive.
Table of Contents
- Introduction
- Key Components
- Using Accessibility Features
- Semantic Labels
- Screen Reader Support
- Touch Targets
- High Contrast and Dynamic Text
- Best Practices
Introduction
Accessibility is essential for ensuring your app can be used by everyone, including people with disabilities. The Flutter Riverpod Clean Architecture template includes comprehensive accessibility support to help you build inclusive applications.
Key Components
The accessibility module consists of several key components:
AccessibilityService
: Interface for accessing device accessibility settingsFlutterAccessibilityService
: Implementation of the accessibility serviceAccessibilitySettings
: Class representing current accessibility settingsAccessibilityWrapper
: Widget that applies accessibility settings to child widgets- Extension methods for adding accessibility features to widgets
- Accessible widgets (
AccessibleButton
,AccessibleTextField
, etc.)
Using Accessibility Features
Wrapping Your App
The application is already wrapped with the AccessibilityWrapper
in main.dart
:
return AccessibilityWrapper(
child: MaterialApp.router(
// App configuration
),
);
This automatically applies device accessibility settings (font scaling, animations, etc.) to your app.
Adding Accessibility to Widgets
Use the extension methods to add accessibility features to your widgets:
// Increase touch target size
myButton.withMinimumTouchTargetSize()
// Add semantic labels
myImage.withSemanticLabel('Profile picture of John Doe')
// Add accessible tooltips
myIcon.withAccessibleTooltip('Delete item')
// Exclude decorative elements from screen readers
decorativeElement.excludeFromSemantics()
Using Accessible Widgets
Use the pre-built accessible widgets for common UI components:
AccessibleButton(
onPressed: () => doSomething(),
semanticLabel: 'Save changes',
child: Text('Save'),
)
AccessibleTextField(
controller: myController,
semanticLabel: 'Email address',
hintText: 'Enter your email',
)
AccessibleSwitch(
value: isEnabled,
onChanged: (value) => setEnabled(value),
semanticLabel: 'Enable notifications',
)
Semantic Labels
Semantic labels provide context for screen reader users. Always include clear, descriptive labels:
Image.asset(
'assets/images/logo.png',
semanticLabel: 'Company logo',
)
IconButton(
icon: Icon(Icons.delete),
onPressed: () => deleteItem(),
tooltip: 'Delete item', // This becomes the semantic label
)
Screen Reader Support
Announcing Changes
Use the announce
method to inform screen reader users of important changes:
final accessibilityNotifier = ref.read(accessibilitySettingsProvider.notifier);
accessibilityNotifier.announce('Order successfully placed');
Custom Semantics
For complex widgets, use the Semantics
widget to provide detailed information:
Semantics(
label: 'Progress bar',
value: '$progressPercent%',
child: LinearProgressIndicator(value: progress),
)
Touch Targets
Ensure all interactive elements are large enough to be easily tapped:
// Using the extension method
IconButton(/*...*/).withMinimumTouchTargetSize()
// Or directly
SizedBox(
width: AppConstants.accessibilityTouchTargetMinSize,
height: AppConstants.accessibilityTouchTargetMinSize,
child: Center(child: IconButton(/*...*/)),
)
High Contrast and Dynamic Text
The AccessibilityWrapper
automatically handles:
- Text scaling based on user preferences
- High contrast mode
- Bold text
- Reduced motion
You can access these settings directly:
final accessibilitySettings = ref.watch(accessibilitySettingsProvider);
if (accessibilitySettings.isHighContrastEnabled) {
// Use high contrast colors
}
if (accessibilitySettings.isReduceMotionEnabled) {
// Skip animations
}
Best Practices
- Test with screen readers: Regularly test your app with TalkBack (Android) and VoiceOver (iOS)
- Use semantic labels: Add descriptive labels to all interactive elements
- Provide text alternatives: Include alt text for images and icons
- Ensure sufficient contrast: Use colors with good contrast ratios
- Support keyboard navigation: Make sure all features are accessible via keyboard
- Group related elements: Use
MergeSemantics
to group related elements - Test font scaling: Ensure your UI works with different text sizes
- Avoid time-based interactions: Don't require quick reactions from users
Remember that accessibility benefits everyone, not just users with disabilities!