From ef467c8d9528d4d4f0dab1158e862e6cd57fcaa8 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Wed, 23 Mar 2011 10:51:55 -0700 Subject: docs: add document for accessibility, authored by Cheryl Simon (clsimon) Change-Id: If4f6e4f12953ae5b608efebde1ac9d3f0720035a --- docs/html/guide/practices/design/accessibility.jd | 352 ++++++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 docs/html/guide/practices/design/accessibility.jd (limited to 'docs/html/guide/practices/design') diff --git a/docs/html/guide/practices/design/accessibility.jd b/docs/html/guide/practices/design/accessibility.jd new file mode 100644 index 0000000..dec815f --- /dev/null +++ b/docs/html/guide/practices/design/accessibility.jd @@ -0,0 +1,352 @@ +page.title=Designing for Accessibility +@jd:body + + +
+
+ +

Quickview

+
    +
  • To make your application more accessible, you should make sure your UI is navigable +using a directional controller and your widgets provide content descriptions
  • +
  • If you implement a custom view, you should ensure that it delivers the appropriate +accessibility events during user interaction
  • +
+ +

In this document

+
    +
  1. Allow Navigation with a Directional Controller +
      +
    1. Controlling focus order
    2. +
    3. Clicking with the a directional controller
    4. +
    +
  2. +
  3. Label Your Input Widgets
  4. +
  5. Follow Android UI Best Practices
  6. +
  7. Send Accessibility Events from Custom View Components
  8. +
  9. Test Your Application’s Accessibility
  10. +
+ +

Key classes

+
    +
  1. {@link android.view.accessibility.AccessibilityEvent}
  2. +
  3. {@link android.view.accessibility.AccessibilityEventSource}
  4. +
+ +

Related samples

+
    +
  1. Accessibility Service
  2. +
+ +
+
+ + + +

Many Android users have disabilities that require them to interact with their Android devices in +different ways. These include users who have visual, physical or aging-related disabilities that +prevent them from fully using or seeing a touchscreen.

+ +

Android provides an accessibility layer that helps these users navigate their Android-powered +devices more easily. Android's accessibility services provide things like text-to-speech, haptic +feedback and trackball/D-pad navigation that augment the user experience.

+ +

Your application should follow the guidelines in this document to ensure that it provides a +good experience for users with disabilities.

+ +

Following these two basic rules will solve most access-related problems:

+ + + + + + + +

Many Android devices come with some sort of directional controller, such as:

+ + +

All of these directional controllers allow users to navigate the screen without using the +touchscreen. On some devices, a user can also navigate to the top or bottom of a list by holding +down the alt key while pressing a discrete key for up or down.

+ +

A directional controller is the primary means of navigation for users with visual or some +physical impairments (and also for users without impairments when using devices that don't +have a touchscreen). You should verify that all UI controls in your application are +accessible without using the touchscreen and that clicking with the center button (or OK button) has +the same effect as touching the controls on the touchscreen.

+ +

A UI control (also called a "widget") is accessible using directional controls when it's +"focusable" property is "true." This means that users can focus on the widget using the directional +controls and then interact with it. Widgets provided by the Android APIs are focusable by default +and visually indicate focus by changing the widget visual appearance in some way.

+ +

Android provides several APIs that let you control whether a widget is focusable and even +request that a widget be given focus. Such methods include:

+ + + +

When working with a view that is not focusable by default, you can make it focusable from the XML +layout file by setting the {@code android:focusable} attribute to {@code "true"}.

+ + + +

Controlling focus order

+ +

When the user navigates in any direction using the directional controls, focus is passed from one +view to another, as determined by the focus ordering. The ordering of the focus movement is based on +an algorithm which finds the nearest neighbor in a given direction. In rare cases, the default +algorithm may not match the order that you intended for your UI. In these situations, you can +provide explicit overrides to the ordering using the following XML attributes in the layout +file:

+ +
+
{@code android:nextFocusDown}
+
Defines the next view to receive focus when the user navigates down.
+ {@code android:nextFocusLeft} +
Defines the next view to receive focus when the user navigates left.
+
{@code android:nextFocusRight}
+
Defines the next view to receive focus when the user navigates right.
+
{@code android:nextFocusUp}
+
Defines the next view to receive focus when the user navigates up.
+
+ +

For example, here is an XML layout that contains a focusable {@link android.widget.TextView}. +While the {@link android.widget.TextView} is located to the right of the {@link +android.widget.EditText}, it can now be reached by pressing the down arrow when focus is on the +{@link android.widget.EditText}:

+ +
+<LinearLayout android:orientation="horizontal"
+              ... >
+    <EditText android:id="@+id/edit"
+              android:nextFocusDown=”@+id/text”
+              ... />
+    <TextView android:id="@+id/text"
+              android:focusable=”true”
+              android:text="Hello, I am a focusable TextView"
+              android:nextFocusUp=”@id/edit”
+              ... />
+</LinearLayout>
+
+ +

When modifying this ordering, be sure that the navigation works as expected in all directions +from each widget and when navigating in reverse (to get back to where you came from).

+ +

You can also modify the focus ordering at runtime, using methods in the {@link +android.view.View} class, such as {@link android.view.View#setNextFocusDownId +setNextFocusDownId()} and {@link android.view.View#setNextFocusRightId +setNextFocusRightId()}.

+ + +

Clicking with the a directional controller

+ +

On most devices, clicking a view using a directional controller sends a {@link +android.view.KeyEvent} with {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} to the view currently +in focus. Make sure this event has the same effect as touching the view on the touchscreen. All +standard Android views already handle {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} +appropriately.

+ +

If possible, also treat the {@link android.view.KeyEvent#KEYCODE_ENTER} event the same as +{@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}. That makes interaction much easier from a full +keyboard.

+ + + + +

Label Your Input Widgets

+ +

Many input widgets rely on visual cues to inform the user of their meaning. For example, a +notepad application might use an {@link android.widget.ImageButton} with a picture of a plus sign to +indicate that the user can add a new note. Or, an {@link android.widget.EditText} may have +a label near it that indicates its purpose. When a visually impaired user accesses your +application, these visual cues are often useless.

+ +

To provide textual information about these widgets (as an alternative to the visual cues), you +should use the {@code android:contentDescription} attribute. The text you provide in this attribute +is not visible on the screen, but if a user has enabled accessibility speech tools then the +description in this attribute is read aloud to the user.

+ +

You should set the {@code +android:contentDescription} attribute on every {@link android.widget.ImageButton}, {@link +android.widget.EditText}, {@link android.widget.CheckBox}, and on any other input widgets that might +benefit users with extra information.

+ +

For example, the following {@link android.widget.ImageButton} sets the content description for +the plus button to the {@code add_note} string resource, which might be defined in English as +“Add note":

+ +
+<ImageButton
+    android:id=”@+id/add_entry_button”
+    android:src=”@drawable/plus”
+    android:contentDescription=”@string/add_note”/>
+
+ +

This way, when using speech accessibility tools, the user hears "Add note" when focused on +this widget.

+ + + +

Follow Android UI Best Practices

+ +

You can make it easier for users to learn how to use your application by developing a user +interface that complies with Android's standard interaction patterns, instead of creating your own +or using interaction patterns from another platform. This consistency is especially important for +many disabled users, as they may have less contextual information available to try to understand +your application’s interface.

+ +

Specifically, you should:

+ + + + + +

Send Accessibility Events from Custom View Components

+ +

If your application requires that you create a custom view component, you may need to +do some additional work to ensure that your view is accessible. Specifically, you should make sure +that your view implements the {@link android.view.accessibility.AccessibilityEventSource} +interface and emits {@link android.view.accessibility.AccessibilityEvent}s at the proper times, +and that each {@link android.view.accessibility.AccessibilityEvent} contains relevant information +about the state of the view.

+ +

Events are emitted whenever something notable happens in the user interface. Currently, there +are five types of accessibility events that a view should send to the system as the user interacts +with it:

+ +
+
{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED}
+
Indicates that the user clicked on the view (for example, the user selects a button).
+ +
{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
+
Indicates that the user performed a long press on the view.
+ +
{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED}
+
Indicates that the user selected an item from within the view. This is usually used in the +context of an {@link android.widget.AdapterView}.
+ +
{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED}
+
Indicates that the user moved the focus to the view.
+ +
{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
+
Indicates that the text or contents of the view changed.
+
+ + +

The basic {@link android.view.View} class implements {@link +android.view.accessibility.AccessibilityEventSource} and emits these events at the proper time in +the standard cases. Your custom view should extend from {@link android.view.View} (or one of its +subclasses) to take advantage of these default implementations.

+ +

Depending on the specifics of your custom view, your view may need to emit one of these events at +a different time than the default {@link android.view.View} implementation. To do so, simply call +{@link android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent +sendAccessibilityEvent()} with the specific event type at the correct time.

+ +

For example, say you are implementing a custom slider bar that allows the user to select a +numeric value by pressing the left or right arrows. This view should emit an event of type {@link +android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} whenever the slider value +changes:

+ +
+@Override
+public boolean onKeyUp (int keyCode, KeyEvent event) {
+  if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
+    mCurrentValue--;
+    sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+    return true;
+  }
+  ...
+}
+
+ +

Each {@link android.view.accessibility.AccessibilityEvent} has a set of required properties that +describe the current state of the view. These properties include things like the view’s class name, +text and checked state. The specific properties required for each event type are described in the +{@link android.view.accessibility.AccessibilityEvent} documentation. The {@link android.view.View} +implementation will fill in default values for these properties. Most of these values, like the +class name and event timestamp, will not need to be changed. However, depending on the specifics of +your custom view, you may want to provide a different value for one or more of the properties. For +example, your view may have additional state information that you want to add to the event text.

+ +

The {@link android.view.View#dispatchPopulateAccessibilityEvent +dispatchPopulateAccessibilityEvent()} method in {@link android.view.View} provides a hook for making +changes to the {@link android.view.accessibility.AccessibilityEvent} object before it is +emitted.

+ +

In the above slider bar example, the view should add the current value of the slider bar to the +text of the event:

+ +
+@Override
+public boolean dispatchPopulateAccessibilityEvent(final AccessibilityEvent event) {
+  super.dispatchPopulateAccessibilityEvent(event);
+  if (!isShown()) {
+    return false;
+  }
+  CharSequence text = String.valueOf(mCurrentValue);
+  if (text.length() > AccessibilityEvent.MAX_TEXT_LENGTH) {
+    text = text.subSequence(0, AccessiblityEvent.MAX_TEXT_LENGTH);
+  }
+  event.getText().add(text);
+  return true;
+}
+
+ + +

Test Your Application’s Accessibility

+ +

You can simulate the experience for many users by enabling an accessibility service that speaks +as you move around the screen. One such service is TalkBack, by the +Eyes-Free Project. It comes preinstalled on many +Android-powered devices, but is also available for free from Android +Market.

+ +

This service requires that you have a text-to-speech engine installed on your phone. You can +verify if you have one installed in the Text-to-speech settings menu by selecting +Listen to an example. If you do not hear anything spoken, install the required +voice data by selecting Install voice data.

+ +

Once text-to-speech is functioning correctly, you can enable TalkBack (or another accessibility +service) in the Accessibility settings menu. Enable both +Accessibility and TalkBack. As you navigate about the device, you +should now hear spoken feedback.

+ +

You can now attempt to use your application as a blind user would. As you move around using only +the directional controller, make sure that the spoken feedback you hear makes sense and is +sufficient to navigate the application without any visual cues.

-- cgit v1.1