Android Accessibility Excellence ♿🛡️
Standard practices for creating inclusive, easy-to-use Android applications that comply with WCAG 2.1+ standards.
⚡ When to Use
- Accessibility Audit: Reviewing current UI for screen reader issues.
- Compose Semantics: Customizing how UI elements are announced.
- Contrast Ratios: Ensuring text is readable for low-vision users.
- Screen Reader Support: Optimizing navigation with TalkBack.
- Touch Target Sizes: Ensuring buttons and links are easy to hit.
🏗️ The 4 Principles (POUR)
- Perceivable: Users can perceive all info via sight, sound, or touch.
- Operable: Users can interact with the app via various methods.
- Understandable: UI and navigation are predictable.
- Robust: Compatible with many assistive tools.
🛠️ Compose Semantics Essentials
1. contentDescription
- Rule: Every
Image,IconButton, or clickable decorative icon MUST have a descriptivecontentDescription. - Bad:
contentDescription = "icon"ornullfor meaningful icons. - Good:
contentDescription = "Search for products"orcontentDescription = nullfor purely decorative items.
2. Semantic Properties
- Use
Modifier.semantics { ... }for custom descriptions or element roles. - Use
Modifier.clearAndSetSemantics { ... }to hide complex child hierarchies from screen readers.
3. Merging Descendants
- For a list item, use
Modifier.semantics(mergeDescendants = true)to announce the whole item at once.Row(modifier = Modifier.semantics(mergeDescendants = true).clickable { ... }) { Text("Order #123") Text("Status: Shipped") }
📐 Design Best Practices
- Contrast: Aim for 4.5:1 for normal text and 3:1 for large text.
- Touch Targets: Minimum size of 48dp x 48dp.
- Dynamic Type: Ensure layouts resize correctly for large font scales (
@PreviewFontScales).
🧪 Testing and Verification
- Accessibility Scanner: Use the Google app to automatically scan screens for common issues.
- TalkBack: Manually test with the screen reader enabled on a physical device.
- Lint Checks: Enable
@LintRulefor missingcontentDescription.
📜 Checklist for Developers
- Descriptive Labels: All actionable items state their purpose (e.g., "Delete Comment" vs "Delete").
- State Announcements: Use
liveRegionorAnnounceAccessibilityEventfor dynamic updates (e.g., "Added to cart"). - Navigation Order: Ensure focus moves in a logical left-to-right, top-to-bottom order.
- Role Identification: Mark elements as buttons, checkboxes, or headers.