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