Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Accessbility and Android APIs

Accessbility and Android APIs

Aung Kyaw Paing

November 19, 2022

Transcript

71 slides
  1. Accessibility and Android APIs Aung Kyaw Paing (Vincent) Senior Consultant

    @ thoughtworks | GDE Thailand aungkyawpaing.dev
  2. Over 1 billion people are estimated to experience disability. This

    corresponds to about 15% of the world's population - World Health Organization (WHO)
  3. Deafness & Hard-of-hearing Motor Impairments Cognitive disabilities Blindness & Visual

    impairment Everyone could experiences one of these in their lives.
  4. - Won “Innovation in Accessibility” award for the first time

    in Game awards - Even people without common disabilities start using these features! The Last of Us
  5. - Integration with braille display - Used together with Talkback

    - Interact using keys on display BrailleBack
  6. Switch Access - Switches instead of taps - Scan items

    and highlight - User can interact with switches
  7. Voice Access - Control hand-free - Show labels and grids

    - Interact device with voice commands
  8. Favorite/Like/Love Search Open Navigation Drawer Label images - Provide a

    screen readable label of your image and actions - Translated for different languages
  9. <ImageView android:id="@+id/event_banner" android:contentDescription="20% discount sale event" /> <menu> <item android:id="@+id/action_settings"

    android:title="@string/action_settings" android:contentDescription="Settings" /> </menu> view.contentDescription = "Describe me!"
  10. Icon( imageVector = Icons.Filled.KeyboardArrowLeft, contentDescription = "Next" ) Image( bitmap

    = ImageBitmap.imageResource(id = R.id.arrow_next), contentDescription = "" )
  11. Icon( imageVector = Icons.Filled.KeyboardArrowLeft, contentDescription = "Next" ) Image( bitmap

    = ImageBitmap.imageResource(id = R.id.arrow_next), contentDescription = "" ) Text( text = "Hello There", modifier = Modifier.semantics { contentDescription = "General Kenobi" } )
  12. <ImageView android:id="@+id/event_banner" android:contentDescription="@null" /> <!-- Only for SDK 16 and

    above --> <ImageView android:id="@+id/event_banner" android:importantForAccessibility="no" />
  13. fun InboxRow() { Row( modifier = Modifier .semantics { onClick(label

    = "Delete") { deleteMail() return@onClick true } } ) { // Render Contents } }
  14. fun InboxRow() { Row( modifier = Modifier .semantics { onClick(label

    = "Delete") { deleteMail() return@onClick true } } ) { // Render Contents } }
  15. fun InboxRow() { Row( modifier = Modifier .semantics { onClick(label

    = "Delete") { deleteMail() return@onClick true } } ) { // Render Contents } }
  16. @Composable fun ClickableRow( text: String, onClick: () -> Unit )

    { Row( modifier = Modifier .clickable() { onClick() } ) { //Render Text and Arrow Right Icon } } “Double tap to click”
  17. @Composable fun ClickableRow( text: String, onClick: () -> Unit )

    { Row( modifier = Modifier .clickable(onClickLabel = "Open $text") { onClick() } ) { //Render Text and Arrow Right Icon } } “Double tap to open $text”
  18. Merge components - Merge views to make screen reader navigate

    with fewer taps - Recommend to use for Lists + “Checkbox Checked” “With Soup” “Checkbox With Soup - Checked”
  19. <ConstraintLayout android:id="@+id/project_container" ... android:screenReaderFocusable="true" android:contentDescription="droiconsg built 3 hours ago"> <TextView

    android:id="@+id/project_title" ... android:focusable="false" android:text="droidconsg" /> <TextView android:id="@+id/build_time" android:focusable="false" android:text="3 Hours Ago" /> </ConstraintLayout>
  20. fun ProjectCard() { Column(modifier = Modifier.Semantic( mergeDescendants = true )

    { //Other accessibility stuffs }) { Text("droidconsg") Text("3 Hours Ago") } }
  21. fun ProjectCard() { Column(modifier = Modifier.Semantic( mergeDescendants = true )

    { onClick(label = "Do Something") { //On Click actions } }) { BookmarkButton() } }
  22. fun ProjectCard() { Column(modifier = Modifier.Semantic( mergeDescendants = true )

    { onClick(label = "Do Something") { //On Click actions } }) { BookmarkButton(modifier = Modifier.clearAndSetSemantics { }) } }
  23. Describe the state - Telling screen reader to alert user

    for state change on interaction Paused Playing Image ref: https://medium.com/google-dev eloper-experts/state-description s-on-android-b2029283871f
  24. Timeout - Do not use constant timeouts - Instead, use

    recommended timeout from Accessibility manager
  25. Anti-patterns - Do not reinvent the wheel - Use material

    or androidx components as much as possible - Do not abuse accessibility announcements val event = AccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT) event.text.add("You got a new notification!") accessibilityManager.sendAccessibilityEvent(event)
  26. Anti-patterns - Do not reinvent the wheel - Use material

    or androidx components as much as possible - Do not abuse accessibility announcements val event = AccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT) event.text.add("You got a new notification!") accessibilityManager.sendAccessibilityEvent(event)
  27. Check List - Adjust button sizes, text sizes and color

    contrast - Label images - Skip unnecessary elements - Provide accessibility actions - Replace with meaningful actions - Adjust timeout - Merge elements
  28. Automated Testing - Espresso provides a one-line code to test

    accessibility - Runs a list of test every time you interact with the view in a test class EspressoTest { init { AccessibilityChecks.enable() } }
  29. Automated Testing There were 2 accessibility errors: AppCompatImageButton{id=2131165210, ...}: View

    is missing speakable text needed for a screen reader, AppCompatImageButton{id=2131165210,...}: View falls below the minimum recommended size ... ...
  30. Compose UI Test composeTestRule .onNodeWithContentDescription("Content Description") .assertIsDisplayed() val matcher =

    hasStateDescription("state value") composeTestRule.onNode(matcher).assertIsDisplayed()
  31. “Accessibility isn’t something that you check the list and say

    it’s done. It’s an user experience so you have to test it manually by yourself to know it’s a good experience”

More Decks by Aung Kyaw Paing

Other Decks in Technology