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<ImageButton 122e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez android:id=”@+id/add_note_button” 123e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez android:src=”@drawable/add_note” 124e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez android:contentDescription=”@string/add_note”/> 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<LinearLayout android:orientation="horizontal" 215e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez ... > 216e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez <EditText android:id="@+id/edit" 217e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez android:nextFocusDown=”@+id/text” 218e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez ... /> 219e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez <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/edit” 223e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez ... /> 224e1302edd40c5cc264f842e17e3796e0a11d6f045Joe Fernandez</LinearLayout> 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 <sdk>/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@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@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 @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 @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 @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 <sdk>/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 @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 @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