1page.title=Making Applications Accessible
2parent.title=Accessibility
3parent.link=index.html
4@jd:body
5
6<div id="qv-wrapper">
7<div id="qv">
8
9  <h2>In this document</h2>
10  <ol>
11    <li><a href="#label-ui">Labeling User Interface Elements</a></li>
12    <li><a href="#focus-nav">Enabling Focus Navigation</a>
13      <ol>
14        <li><a href="#focus-enable">Enabling view focus</a></li>
15        <li><a href="#focus-order">Controlling focus order</a></li>
16      </ol>
17    </li>
18    <li><a href="#custom-views">Building Accessible Custom Views</a>
19      <ol>
20        <li><a href="#directional-control">Handling directional controller clicks</a></li>
21        <li><a href="#accessibility-methods">Implementing accessibility API methods</a></li>
22        <li><a href="#send-events">Sending accessibility events</a></li>
23        <li><a href="#populate-events">Populating accessibility events</a></li>
24        <li><a href="#virtual-hierarchy">Providing a customized accessibility context</a></li>
25        <li><a href="#custom-touch-events">Handling custom touch events</a></li>
26      </ol>
27    </li>
28    <li><a href="#test">Testing Accessibility</a></li>
29  </ol>
30
31  <h2>Key classes</h2>
32  <ol>
33    <li>{@link android.view.accessibility.AccessibilityEvent}</li>
34    <li>{@link android.view.accessibility.AccessibilityNodeInfo}</li>
35    <li>{@link android.support.v4.view.accessibility.AccessibilityNodeInfoCompat}</li>
36    <li>{@link android.view.View.AccessibilityDelegate}</li>
37    <li>{@link android.support.v4.view.AccessibilityDelegateCompat}</li>
38  </ol>
39
40  <h2>See also</h2>
41  <ol>
42    <li><a href="checklist.html">Accessibility Developer Checklist</a><li>
43    <li><a href="{@docRoot}tools/testing/testing_accessibility.html">Accessibility Testing Checklist</a><li>
44    <li><a href="{@docRoot}design/patterns/accessibility.html">Android Design: Accessibility</a></li>
45    <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a></li>
46    <li><a href="{@docRoot}training/accessibility/index.html">Training: Implementing Accessibility</a></li>
47  </ol>
48
49</div>
50</div>
51
52<p>Applications built for Android are more accessible to users with visual, physical or age-related
53limitations when those users activate accessibility services and features on a device. These
54services make your application more accessible even if you do not make any accessibility changes
55to your code. However, there are steps you should take to optimize the accessibility of your
56application and ensure a pleasant experience for all your users.</p>
57
58<p>Making sure your application is accessible to all users requires only a few steps, particularly
59when you create your user interface with the components provided by the Android framework. If you
60use only the standard components for your application, the steps are:</p>
61
62<ol>
63  <li>Add descriptive text to user interface controls in your application using the
64    <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
65    {@code android:contentDescription}</a> attribute. Pay particular attention to
66    {@link android.widget.ImageButton}, {@link android.widget.ImageView}
67    and {@link android.widget.CheckBox}.</li>
68  <li>Make sure that all user interface elements that can accept input (touches or typing) can be
69    reached with a directional controller, such as a trackball, D-pad (physical or virtual) or
70    navigation <a href="http://support.google.com/android/bin/topic.py?hl=en&topic=2492346">gestures
71    </a>.</li>
72  <li>Make sure that audio prompts are always accompanied by another visual prompt or notification,
73    to assist users who are deaf or hard of hearing.</li>
74  <li>Test your application using only accessibility navigation services and features. Turn on
75    <a href="{@docRoot}tools/testing/testing_accessibility.html#testing-talkback">TalkBack</a> and
76    <a href="{@docRoot}tools/testing/testing_accessibility.html#testing-ebt">Explore by Touch</a>,
77    and then try using your application using only directional controls. For more information on
78    testing for accessibility, see the <a href="{@docRoot}tools/testing/testing_accessibility.html">
79    Accessibility Testing Checklist</a>.</li>
80</ol>
81
82<p>If you build custom controls that extend the {@link android.view.View} class, you must complete
83some additional work to make sure your components are accessible. This document discusses how to
84make custom view controls compatible with accessibility services.</p>
85
86<p class="note">
87<strong>Note:</strong> The implementation steps in this document describe the requirements for
88making your application accessible for users with blindness or low-vision. Be sure to review the
89requirements for serving users who are deaf and hard of hearing in the
90<a href="{@docRoot}guide/topics/ui/accessibility/checklist.html">Accessibility Developer
91Checklist</a></p>.
92
93
94
95<h2 id="label-ui">Labeling User Interface Elements</h2>
96
97<p>Many user interface controls depend on visual cues to indicate their meaning and usage. For
98example, a note-taking application might use an {@link android.widget.ImageButton} with a
99picture of a plus sign to indicate that the user can add a new note. An {@link
100android.widget.EditText} component may have a label near it that indicates its purpose. A user
101with impaired vision can't see these cues well enough to follow them, which makes them useless.</p>
102
103<p>You can make these controls more accessible with the
104<a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
105{@code android:contentDescription}</a> XML layout attribute. The text in this attribute does not
106appear on screen, but if the user enables accessibility services that provide audible prompts, then
107when the user navigates to that control, the text is spoken.</p>
108
109<p>For this reason, set the
110<a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
111{@code android:contentDescription}</a> attribute for every {@link android.widget.ImageButton},
112{@link android.widget.ImageView}, {@link android.widget.CheckBox}
113in your application's user interface, and add descriptions to any other input controls that might
114require additional information for users who are not able to see it.</p>
115
116<p>For example, the following {@link android.widget.ImageButton} sets the content description for
117the plus button to the {@code add_note} string resource, which could be defined as “Add note" for an
118English language interface:</p>
119
120<pre>
121&lt;ImageButton
122    android:id=”@+id/add_note_button123    android:src=”@drawable/add_note124    android:contentDescription=”@string/add_note”/&gt;
125</pre>
126
127<p>By including the description, an accessibility service that provides spoken feedback can announce
128"Add note" when a user moves focus to this button or hovers over it.</p>
129
130<p class="note"><strong>Note:</strong> For {@link android.widget.EditText} fields, provide an
131<a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">android:hint</a>
132attribute <em>instead</em> of a content description, to help users understand what content is
133expected when the text field is empty. When the field is filled, TalkBack reads the entered
134content to the user, instead of the hint text.</p>
135
136
137<h2 id="focus-nav">Enabling Focus Navigation</h2>
138
139<p>Focus navigation allows users with disabilities to step through user interface controls using a
140directional controller. Directional controllers can be physical, such as a trackball, directional
141pad (D-pad) or arrow keys, or virtual, such as the
142<a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin">
143Eyes-Free Keyboard</a>, or the gestures navigation mode available in Android 4.1 and higher.
144Directional controllers are a primary means of navigation for many Android users.
145</p>
146
147<p>To ensure that users can navigate your application using only a directional controller, verify
148that all user interface (UI) input controls in your application can be reached and activated
149without using the touchscreen. You should also verify that clicking with the center button (or OK
150button) of a directional controller has the same effect as touching a control that already has
151focus. For information on testing directional controls, see
152<a href="{@docRoot}tools/testing/testing_accessibility.html#test-navigation">Testing
153focus navigation</a>.</p>
154
155
156<h3 id="focus-enable">Enabling view focus</h3>
157
158<p>A user interface element is reachable using directional controls when its
159<a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
160{@code android:focusable}</a> attribute is set to {@code true}. This setting allows users to focus
161on the element using the directional controls and then interact with it. The user interface controls
162provided by the Android framework are focusable by default and visually indicate focus by changing
163the control’s appearance.</p>
164
165<p>Android provides several APIs that let you control whether a user interface control is focusable
166and even request that a control be given focus:</p>
167
168<ul>
169  <li>{@link android.view.View#setFocusable setFocusable()}</li>
170  <li>{@link android.view.View#isFocusable isFocusable()}</li>
171  <li>{@link android.view.View#requestFocus requestFocus()}</li>
172</ul>
173
174<p>If a view is not focusable by default, you can make it focusable in your layout file by setting
175the <a href="{@docRoot}reference/android/view/View.html#attr_android:focusable">
176{@code android:focusable}</a> attribute to {@code true} or by calling the its {@link
177android.view.View#setFocusable setFocusable()} method.</p>
178
179
180<h3 id="focus-order">Controlling focus order</h3>
181
182<p>When users navigate in any direction using directional controls, focus is passed from one
183user interface element (view) to another, as determined by the focus order. This order is based on
184an algorithm that finds the nearest neighbor in a given direction. In rare cases, the algorithm may
185not match the order that you intended or may not be logical for users. In these situations, you can
186provide explicit overrides to the ordering using the following XML attributes in your layout file:
187</p>
188
189<dl>
190  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown">
191  {@code android:nextFocusDown}</a></dt>
192    <dd>Defines the next view to receive focus when the user navigates down.</dd>
193  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft">
194  {@code android:nextFocusLeft}</a></dt>
195    <dd>Defines the next view to receive focus when the user navigates left.</dd>
196  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight">
197  {@code android:nextFocusRight}</a></dt>
198    <dd>Defines the next view to receive focus when the user navigates right.</dd>
199  <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp">
200  {@code android:nextFocusUp}</a></dt>
201    <dd>Defines the next view to receive focus when the user navigates up.</dd>
202</dl>
203
204<p>The following example XML layout shows two focusable user interface elements where the
205<a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown">{@code
206android:nextFocusDown}</a> and
207<a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp">{@code
208android:nextFocusUp}</a> attributes have been explicitly set. The {@link android.widget.TextView} is
209located to the right of the {@link android.widget.EditText}. However, since these properties have
210been set, the {@link android.widget.TextView} element can now be reached by pressing the down arrow
211when focus is on the {@link android.widget.EditText} element:</p>
212
213<pre>
214&lt;LinearLayout android:orientation="horizontal"
215        ... &gt;
216    &lt;EditText android:id="@+id/edit"
217        android:nextFocusDown=”@+id/text218        ... /&gt;
219    &lt;TextView android:id="@+id/text"
220        android:focusable=”true”
221        android:text="Hello, I am a focusable TextView"
222        android:nextFocusUp=”@id/edit223        ... /&gt;
224&lt;/LinearLayout&gt;
225</pre>
226
227<p>When modifying focus order, be sure that the navigation works as expected in all directions from
228each user interface control and when navigating in reverse (to get back to where you came from).</p>
229
230<p class="note"><strong>Note:</strong> You can modify the focus order of user interface components
231at runtime, using methods such as {@link android.view.View#setNextFocusDownId setNextFocusDownId()}
232and {@link android.view.View#setNextFocusRightId setNextFocusRightId()}.</p>
233
234
235<h2 id="custom-views">Building Accessible Custom Views</h2>
236
237<p>If your application requires a <a href="{@docRoot}guide/topics/ui/custom-components.html">custom
238view component</a>, you must do some additional work to ensure that your custom view is accessible.
239These are the main tasks for ensuring the accessibility of your view:</p>
240
241<ul>
242  <li>Handle directional controller clicks</li>
243  <li>Implement accessibility API methods</li>
244  <li>Send {@link android.view.accessibility.AccessibilityEvent} objects specific to your custom
245    view</li>
246  <li>Populate {@link android.view.accessibility.AccessibilityEvent} and {@link
247    android.view.accessibility.AccessibilityNodeInfo} for your view</li>
248</ul>
249
250
251<h3 id="directional-control">Handling directional controller clicks</h3>
252
253<p>On most devices, clicking a view using a directional controller sends a {@link
254android.view.KeyEvent} with {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} to the view currently
255in focus. All standard Android views already handle {@link
256android.view.KeyEvent#KEYCODE_DPAD_CENTER} appropriately. When building a custom {@link
257android.view.View} control, make sure this event has the same effect as touching the view on the
258touchscreen. </p>
259
260<p>Your custom control should also treat the {@link android.view.KeyEvent#KEYCODE_ENTER} event the
261same as {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}. This approach makes interaction from a
262full keyboard much easier for users.</p>
263
264
265<h3 id="accessibility-methods">Implementing accessibility API methods</h3>
266
267<p>Accessibility events are messages about users interaction with visual interface components in
268your application. These messages are handled by <a href="services.html">Accessibility Services</a>,
269which use the information in these events to produce supplemental feedback and prompts. In
270Android 4.0 (API Level 14) and higher, the methods for
271generating accessibility events have been expanded to provide more detailed information than the
272{@link android.view.accessibility.AccessibilityEventSource} interface introduced in Android 1.6 (API
273Level 4). The expanded accessibility methods are part of the {@link android.view.View} class as well
274as the {@link android.view.View.AccessibilityDelegate} class. The methods are as follows:</p>
275
276<dl>
277 <dt>{@link android.view.View#sendAccessibilityEvent sendAccessibilityEvent()}</dt>
278  <dd>(API Level 4) This method is called when a user takes action on a view. The event is
279classified with a user action type such as {@link
280android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED TYPE_VIEW_CLICKED}. You typically do
281not need to implement this method unless you are creating a custom view.</dd>
282
283  <dt>{@link android.view.View#sendAccessibilityEventUnchecked
284sendAccessibilityEventUnchecked()}</dt>
285  <dd>(API Level 4) This method is used when the calling code needs to directly control the check
286for accessibility being enabled on the device ({@link
287android.view.accessibility.AccessibilityManager#isEnabled AccessibilityManager.isEnabled()}). If
288you do implement this method, you must perform the call as if accessibility is enabled, regardless
289of the actual system setting. You typically do not need to implement this method for a custom view.
290</dd>
291
292  <dt>{@link android.view.View#dispatchPopulateAccessibilityEvent
293dispatchPopulateAccessibilityEvent()}</dt>
294  <dd>(API Level 4) The system calls this method when your custom view generates an
295accessibility event. As of API Level 14, the default implementation of this method calls {@link
296android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} for this view and
297then the {@link android.view.View#dispatchPopulateAccessibilityEvent
298dispatchPopulateAccessibilityEvent()} method for each child of this view. In order to support
299accessibility services on revisions of Android <em>prior</em> to 4.0 (API Level 14) you
300<em>must</em> override this method and populate {@link
301android.view.accessibility.AccessibilityEvent#getText} with descriptive text for your custom
302view, which is spoken by accessibility services, such as TalkBack.</dd>
303
304  <dt>{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}</dt>
305  <dd>(API Level 14) This method sets the spoken text prompt of the {@link
306android.view.accessibility.AccessibilityEvent} for your view. This method is also called if the
307view is a child of a view which generates an accessibility event.
308
309  <p class="note"><strong>Note:</strong> Modifying additional attributes beyond the text within
310this method potentially overwrites properties set by other methods. While you can modify
311attributes of the accessibility event with this method, you should limit these changes
312to text content, and use the {@link android.view.View#onInitializeAccessibilityEvent
313onInitializeAccessibilityEvent()} method to modify other properties of the event.</p>
314
315  <p class="note"><strong>Note:</strong> If your implementation of this event completely
316overrides the output text without allowing other parts of your layout to modify its content, then
317do not call the super implementation of this method in your code.</p>
318  </dd>
319
320  <dt>{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}</dt>
321  <dd>(API Level 14) The system calls this method to obtain additional information about the
322state of the view, beyond text content. If your custom view provides interactive control beyond a
323simple {@link android.widget.TextView} or {@link android.widget.Button}, you should override this
324method and set the additional information about your view into the event using this method, such as
325password field type, checkbox type or states that provide user interaction or feedback. If you
326do override this method, you must call its super implementation and then only modify properties
327that have not been set by the super class.</dd>
328
329  <dt>{@link android.view.View#onInitializeAccessibilityNodeInfo
330onInitializeAccessibilityNodeInfo()}</dt>
331  <dd>(API Level 14) This method provides accessibility services with information about the state of
332the view. The default {@link android.view.View} implementation has a standard set of view
333properties, but if your custom view provides interactive control beyond a simple {@link
334android.widget.TextView} or {@link android.widget.Button}, you should override this method and set
335the additional information about your view into the {@link
336android.view.accessibility.AccessibilityNodeInfo} object handled by this method.</dd>
337
338  <dt>{@link android.view.ViewGroup#onRequestSendAccessibilityEvent
339onRequestSendAccessibilityEvent()}</dt>
340  <dd>(API Level 14) The system calls this method when a child of your view has generated an
341{@link android.view.accessibility.AccessibilityEvent}. This step allows the parent view to amend
342the accessibility event with additional information. You should implement this method only if your
343custom view can have child views and if the parent view can provide context information to the
344accessibility event that would be useful to accessibility services.</dd>
345</dl>
346
347<p>In order to support these accessibility methods for a custom view, you should take one of the
348following approaches:</p>
349
350<ul>
351  <li>If your application targets Android 4.0 (API level 14) and higher, override and implement the
352accessibility methods listed above directly in your custom view class.</li>
353  <li>If your custom view is intended to be compatible with Android 1.6 (API Level 4) and above, add
354the Android <a href="{@docRoot}tools/support-library/index.html">Support Library</a>, revision 5 or
355higher, to your project. Then, within your custom view class, call the
356{@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
357ViewCompat.setAccessibilityDelegate()} method to implement the accessibility methods
358above. For an example of this approach, see the Android Support Library (revision 5 or higher)
359sample {@code AccessibilityDelegateSupportActivity} in
360({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/})
361  </li>
362</ul>
363
364<p>In either case, you should implement the following accessibility methods for your custom view
365class:</p>
366
367<ul>
368  <li>{@link android.view.View#dispatchPopulateAccessibilityEvent
369    dispatchPopulateAccessibilityEvent()}</li>
370  <li>{@link android.view.View#onPopulateAccessibilityEvent
371    onPopulateAccessibilityEvent()}</li>
372  <li>{@link android.view.View#onInitializeAccessibilityEvent
373    onInitializeAccessibilityEvent()}</li>
374  <li>{@link android.view.View#onInitializeAccessibilityNodeInfo
375    onInitializeAccessibilityNodeInfo()}</li>
376</ul>
377
378<p>For more information about implementing these methods, see <a href="#populate-events">Populating
379Accessibility Events</a>.</p>
380
381
382<h3 id="send-events">Sending accessibility events</h3>
383
384<p>Depending on the specifics of your custom view, it may need to send {@link
385android.view.accessibility.AccessibilityEvent} objects at a different times or for events not
386handled by the default implementation. The {@link android.view.View} class provides a default
387implementation for these event types:</p>
388
389<ul>
390  <li>Starting with API Level 4:
391    <ul>
392      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED}</li>
393
394      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}</li>
395
396      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED}</li>
397    </ul>
398  </li>
399  <li>Starting with API Level 14:
400    <ul>
401      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED}</li>
402
403      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}</li>
404
405      <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}</li>
406    </ul>
407  </li>
408</ul>
409
410<p class="note"><strong>Note:</strong> Hover events are associated with the Explore by
411Touch feature, which uses these events as triggers for providing audible prompts for user interface
412elements.</p>
413
414<p>In general, you should send an {@link android.view.accessibility.AccessibilityEvent} whenever the
415content of your custom view changes. For example, if you are implementing a custom slider bar that
416allows a user to select a numeric value by pressing the left or right arrows, your custom view
417should emit an event of type {@link
418android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} whenever the slider
419value changes. The following sample code demonstrates the use of the {@link
420android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent
421sendAccessibilityEvent()} method to report this event.</p>
422
423<pre>
424&#64;Override
425public boolean onKeyUp (int keyCode, KeyEvent event) {
426    if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
427        mCurrentValue--;
428        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
429        return true;
430    }
431    ...
432}
433</pre>
434
435
436<h3 id="populate-events">Populating accessibility events</h3>
437
438<p>Each {@link android.view.accessibility.AccessibilityEvent} has a set of required properties that
439describe the current state of the view. These properties include things such as the view’s class
440name, content description and checked state. The specific properties required for each event type
441are described in the {@link android.view.accessibility.AccessibilityEvent} reference documentation.
442The {@link android.view.View} implementation provides default values for these properties. Many of
443these values, including the class name and event timestamp, are provided automatically. If you are
444creating a custom view component, you must provide some information about the content and
445characteristics of the view. This information may be as simple as a button label, but may also
446include additional state information that you want to add to the event.</p>
447
448<p>The minimum requirement for providing information to accessibility services with a custom
449view is to implement {@link android.view.View#dispatchPopulateAccessibilityEvent
450dispatchPopulateAccessibilityEvent()}. This method is called by the system to request
451information for an {@link android.view.accessibility.AccessibilityEvent} and makes your custom
452view compatible with accessibility services on Android 1.6 (API Level 4) and higher. The
453following example code demonstrates a basic implementation of this method.</p>
454
455<pre>
456&#64;Override
457public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
458    super.dispatchPopulateAccessibilityEvent(event);
459    // Call the super implementation to populate its text to the event, which
460    // calls onPopulateAccessibilityEvent() on API Level 14 and up.
461
462    // In case this is running on a API revision earlier that 14, check
463    // the text content of the event and add an appropriate text
464    // description for this custom view:
465    CharSequence text = getText();
466    if (!TextUtils.isEmpty(text)) {
467        event.getText().add(text);
468    }
469}
470</pre>
471
472<p>For Android 4.0 (API Level 14) and higher, use the {@link
473android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
474{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
475methods to populate or modify the information in an {@link
476android.view.accessibility.AccessibilityEvent}. Use the
477{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} method
478specifically for adding or modifying the text content of the event, which is turned into audible
479prompts by accessibility services such as TalkBack. Use the
480{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} method for
481populating additional information about the event, such as the selection state of the view.</p>
482
483<p>In addition, implement the
484{@link android.view.View#onInitializeAccessibilityNodeInfo onInitializeAccessibilityNodeInfo()}
485method. The {@link android.view.accessibility.AccessibilityNodeInfo} objects populated by this method
486are used by accessibility services to investigate the view hierarchy that generated an accessibility
487event after receiving that event, to obtain a more detailed context information and provide
488appropriate feedback to users.</p>
489
490<p>The example code below shows how override these three methods by using
491{@link android.support.v4.view.ViewCompat#setAccessibilityDelegate
492ViewCompat.setAccessibilityDelegate()}. Note that this sample code requires that the Android
493<a href="{@docRoot}tools/support-library/index.html">Support Library</a> for API Level 4 (revision
4945 or higher) is added to your project.</p>
495
496<pre>
497ViewCompat.setAccessibilityDelegate(new AccessibilityDelegateCompat() {
498    &#64;Override
499    public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
500        super.onPopulateAccessibilityEvent(host, event);
501        // We call the super implementation to populate its text for the
502        // event. Then we add our text not present in a super class.
503        // Very often you only need to add the text for the custom view.
504        CharSequence text = getText();
505        if (!TextUtils.isEmpty(text)) {
506            event.getText().add(text);
507        }
508    }
509    &#64;Override
510    public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
511        super.onInitializeAccessibilityEvent(host, event);
512        // We call the super implementation to let super classes
513        // set appropriate event properties. Then we add the new property
514        // (checked) which is not supported by a super class.
515        event.setChecked(isChecked());
516    }
517    &#64;Override
518    public void onInitializeAccessibilityNodeInfo(View host,
519            AccessibilityNodeInfoCompat info) {
520        super.onInitializeAccessibilityNodeInfo(host, info);
521        // We call the super implementation to let super classes set
522        // appropriate info properties. Then we add our properties
523        // (checkable and checked) which are not supported by a super class.
524        info.setCheckable(true);
525        info.setChecked(isChecked());
526        // Quite often you only need to add the text for the custom view.
527        CharSequence text = getText();
528        if (!TextUtils.isEmpty(text)) {
529            info.setText(text);
530        }
531    }
532}
533</pre>
534
535<p>In applications targeting Android 4.0 (API Level 14) and higher, you can implement these methods
536directly in your custom view class. For another example of this approach, see the Android
537<a href="{@docRoot}tools/support-library/index.html">Support Library</a> (revision 5 or higher)
538sample {@code AccessibilityDelegateSupportActivity} in
539({@code &lt;sdk&gt;/extras/android/support/v4/samples/Support4Demos/}).</p>
540
541<p class="note"><strong>Note:</strong> You may find information on implementing accessibility for
542custom views written prior to Android 4.0 that describes the use of the
543{@link android.view.View#dispatchPopulateAccessibilityEvent dispatchPopulateAccessibilityEvent()}
544method for populating AccessibilityEvents. As of the Android 4.0 release, however, the recommended
545approach is to use the
546{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and
547{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}
548methods.</p>
549
550
551<h3 id="virtual-hierarchy">Providing a customized accessibility context</h3>
552
553<p>In Android 4.0 (API Level 14), the framework was enhanced to allow accessibility services to
554  inspect the containing view hierarchy of a user interface component that generates an
555  accessibility event. This enhancement allows accessibility services to provide a much richer set
556  of contextual information with which to aid users.</p>
557
558<p>There are some cases where accessibility services cannot get adequate information
559  from the view hierarchy. An example of this is a custom interface control that has two or more
560  separately clickable areas, such as a calendar control. In this case, the services cannot get
561  adequate information because the clickable subsections are not part of the view hierarchy.</p>
562
563<img src="calendar.png" alt="" id="figure1" />
564<p class="img-caption">
565  <strong>Figure 1.</strong> A custom calendar view with selectable day elements.
566</p>
567
568<p>In the example shown in Figure 1, the entire calendar is implemented as a single view, so if you
569  do not do anything else, accessibility services do not receive enough information about the
570  content of the view and the user's selection within the view. For example, if a user clicks on the
571  day containing <strong>17</strong>, the accessibility framework only receives the description
572  information for the whole calendar control. In this case, the TalkBack accessibility service would
573  simply announce "Calendar" or, only slightly better, "April Calendar" and the user would be left
574  to wonder what day was selected.</p>
575
576<p>To provide adequate context information for accessibility services in situations like this,
577  the framework provides a way to specify a virtual view hierarchy. A <em>virtual view
578  hierarchy</em> is a way for application developers to provide a complementary view hierarchy
579  to accessibility services that more closely matches the actual information on screen. This
580  approach allows accessibility services to provide more useful context information to users.</p>
581
582<p>Another situation where a virtual view hierarchy may be needed is a user interface containing
583  a set of controls (views) that have closely related functions, where an action on one control
584  affects the contents of one or more elements, such as a number picker with separate up and down
585  buttons. In this case, accessibility services cannot get adequate information because action on
586  one control changes content in another and the relationship of those controls may not be apparent
587  to the service. To handle this situation, group the related controls with a containing view and
588  provide a virtual view hierarchy from this container to clearly represent the information and
589  behavior provided by the controls.</p>
590
591<p>In order to provide a virtual view hierarchy for a view, override the {@link
592  android.view.View#getAccessibilityNodeProvider} method in your custom view or view group and
593  return an implementation of {@link android.view.accessibility.AccessibilityNodeProvider}. For an
594  example implementation of this accessibility feature, see
595  {@code AccessibilityNodeProviderActivity} in the ApiDemos sample project. You can implement a
596  virtual view hierarchy that is compatible with Android 1.6 and later by using the
597  <a href="{@docRoot}tools/support-library/index.html">Support Library</a> with the
598  {@link android.support.v4.view.ViewCompat#getAccessibilityNodeProvider
599  ViewCompat.getAccessibilityNodeProvider()} method and providing an implementation with
600  {@link android.support.v4.view.accessibility.AccessibilityNodeProviderCompat}.</p>
601
602
603<h3 id="custom-touch-events">Handling custom touch events</h3>
604
605<p>Custom view controls may require non-standard touch event behavior. For example, a custom
606control may use the {@link android.view.View#onTouchEvent} listener method to detect the
607{@link android.view.MotionEvent#ACTION_DOWN} and {@link android.view.MotionEvent#ACTION_UP} events
608and trigger a special click event. In order to maintain compatibility with accessibility services,
609the code that handles this custom click event must do the following:</p>
610
611<ol>
612  <li>Generate an appropriate {@link android.view.accessibility.AccessibilityEvent} for the
613  interpreted click action.</li>
614  <li>Enable accessibility services to perform the custom click action for users who are not able to
615   use a touch screen.</li>
616</ol>
617
618<p>To handle these requirements in an efficient way, your code should override the
619{@link android.view.View#performClick} method, which must call the super implementation of this
620method and then execute whatever actions are required by the click event. When the custom click
621action is detected, that code should then call your {@code performClick()} method. The following
622code example demonstrates this pattern.</p>
623
624<pre>
625class CustomTouchView extends View {
626
627    public CustomTouchView(Context context) {
628        super(context);
629    }
630
631    boolean mDownTouch = false;
632
633    &#64;Override
634    public boolean onTouchEvent(MotionEvent event) {
635        super.onTouchEvent(event);
636
637        // Listening for the down and up touch events
638        switch (event.getAction()) {
639            case MotionEvent.ACTION_DOWN:
640                mDownTouch = true;
641                return true;
642
643            case MotionEvent.ACTION_UP:
644                if (mDownTouch) {
645                    mDownTouch = false;
646                    performClick(); // Call this method to handle the response, and
647                                    // thereby enable accessibility services to
648                                    // perform this action for a user who cannot
649                                    // click the touchscreen.
650                    return true;
651                }
652        }
653        return false; // Return false for other touch events
654    }
655
656    &#64;Override
657    public boolean performClick() {
658        // Calls the super implementation, which generates an AccessibilityEvent
659        // and calls the onClick() listener on the view, if any
660        super.performClick();
661
662        // Handle the action for the custom click here
663
664        return true;
665    }
666}
667</pre>
668
669<p>The pattern shown above makes sure that the custom click event is compatible with
670accessibility services by using the {@link android.view.View#performClick} method to both generate
671an accessibility event and provide an entry point for accessibility services to act on behalf of a
672user to perform this custom click event.</p>
673
674<p class="note"><strong>Note:</strong> If your custom view has distinct clickable regions, such as
675a custom calendar view, you must implement a <a href="#virtual-hierarchy">virtual view
676hierarchy</a> by overriding {@link android.view.View#getAccessibilityNodeProvider} in your custom
677view in order to be compatible with accessibility services.</p>
678
679
680<h2 id="test">Testing Accessibility</h2>
681
682<p>Testing the accessibility of your application is an important part of ensuring your users have a
683great experience. You can test the most important accessibility features by using your application
684with audible feedback enabled and navigating within your application using only directional
685controls. For more information on testing accessibility in your application, see the
686<a href="{@docRoot}tools/testing/testing_accessibility.html">Accessibility Testing Checklist</a>.
687</p>
688
689