- Home Startseite ホーム 主页 首頁
- SDK
- Dev Guide Handbuch Guía Guide Guida 開発ガイド 开发人员指南 開發指南
- Reference Referenz Referencia Référence Riferimento リファレンス 参考 參考資料
- Resources
- Videos ビデオ
- Blog ブログ 博客 網誌

Android.com

# Designing for Accessibility

## 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. Clicking with a directional controller
2. Label Your Input Widgets
3. Follow Android UI Best Practices
4. Send Accessibility Events from Custom View Components
5. Test Your Application’s Accessibility

## Key classes

1. `AccessibilityEvent`
2. `AccessibilityEventSource`

## Related samples

1. Accessibility Service

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 age-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:

- Make all of your user interface controls accessible with a trackball or directional controller (d-pad).
- Label your `ImageButton`, `EditText`, and other input widgets using the `android:contentDescription` attribute.

## Allow Navigation with a Directional Controller

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

- A clickable trackball that users can move in any direction
- A clickable d-pad that allows users to navigate in four directions.
- Arrow keys and an OK button that’s equivalent to clicking a trackball or d-pad.

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:

- `setFocusable()`
- `isFocusable()`
- `requestFocus()`

When working with a view that is not focusable by default, you can make it focusable from the XML layout file by setting the `android:focusable` attribute to `"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 that 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:

`android:nextFocusDown`
  Defines the next view to receive focus when the user navigates down.
`android:nextFocusLeft`
  Defines the next view to receive focus when the user navigates left.
`android:nextFocusRight`
  Defines the next view to receive focus when the user navigates right.
`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 `TextView`. While the `TextView` is located to the right of the `EditText`, it can now be reached by pressing the down arrow when focus is on the `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 `View` class, such as `setNextFocusDownId()` and `setNextFocusRightId()`.

### Clicking with a directional controller

On most devices, clicking a view using a directional controller sends a `KeyEvent` with `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 `KEYCODE_DPAD_CENTER` appropriately.

If possible, also treat the `KEYCODE_ENTER` event the same as `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 `ImageButton` with a picture of a plus sign to indicate that the user can add a new note. Or, an `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 `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 `android:contentDescription` attribute on every `ImageButton`, `EditText`, `CheckBox`, and on any other input widgets that might benefit users with extra information.

For example, the following `ImageButton` sets the content description for the plus button to the `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:

- Use the platform's built-in widgets and layouts whenever possible, as these views provide accessibility support by default.
- Use the Options Menu as an alternative to complex touchscreen tasks.
- Make sure the BACK button correctly moves the user back one logical step in the task's back stack or the activity's back stack of fragments (when performing fragment transactions), as appropriate.

## 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 `AccessibilityEventSource` interface and emits `AccessibilityEvent`s at the proper times, and that each `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:

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

The basic `View` class implements `AccessibilityEventSource` and emits these events at the proper time in the standard cases. Your custom view should extend from `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 `View` implementation. To do so, simply call `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 `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 `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 `AccessibilityEvent` documentation. The `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 `dispatchPopulateAccessibilityEvent()` method in `View` provides a hook for making changes to the `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.

↑ Go to top