1 page.title=Making Applications Accessible 2 parent.title=Accessibility 3 parent.link=index.html 4 @jd:body 5 6 <div id="qv-wrapper"> 7 <div id="qv"> 8 9 <h2>In this document</h2> 10 <ol> 11 <li><a href="#label-ui">Labeling User Interface Elements</a></li> 12 <li><a href="#focus-nav">Enabling Focus Navigation</a> 13 <ol> 14 <li><a href="#focus-enable">Enabling view focus</a></li> 15 <li><a href="#focus-order">Controlling focus order</a></li> 16 </ol> 17 </li> 18 <li><a href="#custom-views">Building Accessible Custom Views</a> 19 <ol> 20 <li><a href="#directional-control">Handling directional controller clicks</a></li> 21 <li><a href="#accessibility-methods">Implementing accessibility API methods</a></li> 22 <li><a href="#send-events">Sending accessibility events</a></li> 23 <li><a href="#populate-events">Populating accessibility events</a></li> 24 </ol> 25 </li> 26 <li><a href="#test">Testing Accessibility</a> 27 <ol> 28 <li><a href="#test-audibles">Testing audible feedback</a></li> 29 <li><a href="#test-navigation">Testing focus navigation</a></li> 30 </ol> 31 </li> 32 </ol> 33 34 <h2>Key classes</h2> 35 <ol> 36 <li>{@link android.view.accessibility.AccessibilityEvent}</li> 37 <li>{@link android.view.accessibility.AccessibilityNodeInfo}</li> 38 <li>{@link android.support.v4.view.accessibility.AccessibilityNodeInfoCompat}</li> 39 <li>{@link android.view.View.AccessibilityDelegate}</li> 40 <li>{@link android.support.v4.view.AccessibilityDelegateCompat}</li> 41 </ol> 42 43 <h2>See also</h2> 44 <ol> 45 <li><a href="{@docRoot}training/accessibility/index.html">Implementing Accessibility</a></li> 46 <li><a href="{@docRoot}training/design-navigation/index.html">Designing Effective Navigation</a> 47 </li> 48 <li><a href="{@docRoot}design/index.html">Android Design</a></li> 49 </ol> 50 51 </div> 52 </div> 53 54 <p>Applications built for Android are accessible to users with visual, physical or age-related 55 disabilities when they activate accessibility features and services on a device. By default, 56 these services make your application more accessible. However, there are further steps you should 57 take to optimize the accessibility of your application and ensure a pleasant experience for all your 58 users.</p> 59 60 <p>Making sure your application is accessible to all users is relatively easy, particularly when you 61 use framework-provided user interface components. If you only use these standard components for your 62 application, there are just a few steps required to ensure your application is accessible:</p> 63 64 <ol> 65 <li>Label your {@link android.widget.ImageButton}, {@link android.widget.ImageView}, {@link 66 android.widget.EditText}, {@link android.widget.CheckBox} and other user interface controls using 67 the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription"> 68 {@code android:contentDescription}</a> attribute.</li> 69 <li>Make all of your user interface elements accessible with a directional controller, 70 such as a trackball or D-pad.</li> 71 <li>Test your application by turning on accessibility services like TalkBack and Explore by 72 Touch, and try using your application using only directional controls.</li> 73 </ol> 74 75 <p>Developers who create custom controls that extend from the {@link android.view.View} class have 76 some additional responsibilities for making sure their components are accessible for users. This 77 document also discusses how to make custom view controls compatible with accessibility services.</p> 78 79 80 <h2 id="label-ui">Labeling User Interface Elements</h2> 81 82 <p>Many user interface controls rely on visual cues to inform users of their meaning. For 83 example, a note-taking application might use an {@link android.widget.ImageButton} with a 84 picture of a plus sign to indicate that the user can add a new note. Or, an {@link 85 android.widget.EditText} component may have a label near it that indicates its purpose. When a user 86 with impaired vision accesses your application, these visual cues are often useless.</p> 87 88 <p>To provide textual information about interface controls (as an alternative to the visual cues), 89 use the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription"> 90 {@code android:contentDescription}</a> attribute. The text you provide in this attribute is not 91 visible on the screen, but if a user has enabled accessibility services that provide audible 92 prompts, then the description in this attribute is read aloud to the user.</p> 93 94 <p>Set the <a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription"> 95 {@code android:contentDescription}</a> attribute for every {@link android.widget.ImageButton}, 96 {@link android.widget.ImageView}, {@link android.widget.EditText}, {@link android.widget.CheckBox} 97 in your application's user interface, and on any other input controls that might require additional 98 information for users who are not able to see it.</p> 99 100 <p>For example, the following {@link android.widget.ImageButton} sets the content description for 101 the plus button to the {@code add_note} string resource, which could be defined as Add note" for an 102 English language interface:</p> 103 104 <pre> 105 <ImageButton 106 android:id=@+id/add_note_button 107 android:src=@drawable/add_note 108 android:contentDescription=@string/add_note/> 109 </pre> 110 111 <p>By including the description, speech-based accessibility services can announce "Add note" when a 112 user moves focus to this button or hovers over it.</p> 113 114 <p class="note"><strong>Note:</strong> For {@link android.widget.EditText} fields, provide an 115 <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">android:hint</a> 116 attribute to help users understand what content is expected.</p> 117 118 <h2 id="focus-nav">Enabling Focus Navigation</h2> 119 120 <p>Focus navigation allows users with disabilities to step through user interface controls using a 121 directional controller. Directional controllers can be physical, such as a clickable trackball, 122 directional pad (D-pad) or arrow keys, tab key navigation with an attached keyboard or a software 123 application, such as the 124 <a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin"> 125 Eyes-Free Keyboard</a>, that provides an on-screen directional control.</p> 126 127 <p>A directional controller is a primary means of navigation for many users. 128 Verify that all user interface (UI) controls in your application are accessible 129 without using the touchscreen and that clicking with the center button (or OK button) of a 130 directional controller has the same effect as touching the controls on the touchscreen. For 131 information on testing directional controls, see <a href="#test-navigation">Testing focus 132 navigation</a>.</p> 133 134 <h3 id="focus-enable">Enabling view focus</h3> 135 136 <p>A user interface element is accessible using directional controls when its 137 <a href="{@docRoot}reference/android/view/View.html#attr_android:focusable"> 138 {@code android:focusable}</a> attribute is set to {@code true}. This setting allows users to focus 139 on the element using the directional controls and then interact with it. The user interface controls 140 provided by the Android framework are focusable by default and visually indicate focus by changing 141 the controls appearance.</p> 142 143 <p>Android provides several APIs that let you control whether a user interface control is focusable 144 and even request that a control be given focus:</p> 145 146 <ul> 147 <li>{@link android.view.View#setFocusable setFocusable()}</li> 148 <li>{@link android.view.View#isFocusable isFocusable()}</li> 149 <li>{@link android.view.View#requestFocus requestFocus()}</li> 150 </ul> 151 152 <p>When working with a view that is not focusable by default, you can make it focusable from the XML 153 layout file by setting the 154 <a href="{@docRoot}reference/android/view/View.html#attr_android:focusable"> 155 {@code android:focusable}</a> attribute to {@code true} or by using the {@link 156 android.view.View#setFocusable setFocusable()} method.</p> 157 158 <h3 id="focus-order">Controlling focus order</h3> 159 160 <p>When users navigate in any direction using directional controls, focus is passed from one 161 user interface element (View) to another, as determined by the focus ordering. The ordering of the 162 focus movement is based on an algorithm that finds the nearest neighbor in a given direction. In 163 rare cases, the default algorithm may not match the order that you intended for your UI. In these 164 situations, you can provide explicit overrides to the ordering using the following XML attributes in 165 the layout file:</p> 166 167 <dl> 168 <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown" 169 >{@code android:nextFocusDown}</a></dt> 170 <dd>Defines the next view to receive focus when the user navigates down.</dd> 171 <a><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusLeft" 172 >{@code android:nextFocusLeft}</a></dt> 173 <dd>Defines the next view to receive focus when the user navigates left.</dd> 174 <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusRight" 175 >{@code android:nextFocusRight}</a></dt> 176 <dd>Defines the next view to receive focus when the user navigates right.</dd> 177 <dt><a href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp" 178 >{@code android:nextFocusUp}</a></dt> 179 <dd>Defines the next view to receive focus when the user navigates up.</dd> 180 </dl> 181 182 <p>The following example XML layout shows two focusable user interface elements where the <a 183 href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusDown" 184 >{@code android:nextFocusDown}</a> and <a 185 href="{@docRoot}reference/android/view/View.html#attr_android:nextFocusUp" 186 >{@code android:nextFocusUp}</a> attributes have been explicitly set. The {@link android.widget.TextView} is 187 located to the right of the {@link android.widget.EditText}. However, since these properties have 188 been set, the {@link android.widget.TextView} element can now be reached by pressing the down arrow 189 when focus is on the {@link android.widget.EditText} element: </p> 190 191 <pre> 192 <LinearLayout android:orientation="horizontal" 193 ... > 194 <EditText android:id="@+id/edit" 195 android:nextFocusDown=@+id/text 196 ... /> 197 <TextView android:id="@+id/text" 198 android:focusable=true 199 android:text="Hello, I am a focusable TextView" 200 android:nextFocusUp=@id/edit 201 ... /> 202 </LinearLayout> 203 </pre> 204 205 <p>When modifying focus order, be sure that the navigation works as expected in all directions from 206 each user interface control and when navigating in reverse (to get back to where you came from).</p> 207 208 <p class="note"><strong>Note:</strong> You can modify the focus order of user interface components 209 at runtime, using methods such as {@link android.view.View#setNextFocusDownId setNextFocusDownId()} 210 and {@link android.view.View#setNextFocusRightId setNextFocusRightId()}.</p> 211 212 213 <h2 id="custom-views">Building Accessible Custom Views</h2> 214 215 <p>If your application requires a <a href="{@docRoot}guide/topics/ui/custom-components.html">custom 216 view component</a>, you must do some additional work to ensure that your custom view is accessible. 217 These are the main tasks for ensuring the accessibility of your view:</p> 218 219 <ul> 220 <li>Handle directional controller clicks</li> 221 <li>Implement Accessibility API methods</li> 222 <li>Send {@link android.view.accessibility.AccessibilityEvent} objects specific to your custom view</li> 223 <li>Populate {@link android.view.accessibility.AccessibilityEvent} and {@link 224 android.view.accessibility.AccessibilityNodeInfo} for your view</li> 225 </ul> 226 227 228 <h3 id="directional-control">Handling directional controller clicks</h3> 229 230 <p>On most devices, clicking a view using a directional controller sends a {@link 231 android.view.KeyEvent} with {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER} to the view currently 232 in focus. All standard Android views already handle {@link 233 android.view.KeyEvent#KEYCODE_DPAD_CENTER} appropriately. When building a custom {@link 234 android.view.View} control, make sure this event has the same effect as touching the view on the 235 touchscreen. </p> 236 237 <p>Your custom control should also treat the {@link android.view.KeyEvent#KEYCODE_ENTER} event the 238 same as {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER}. This approach makes interaction from a 239 full keyboard much easier for users.</p> 240 241 242 <h3 id="accessibility-methods">Implementing accessibility API methods</h3> 243 244 <p>Accessibility events are messages about users interaction with visual interface components in 245 your application. These messages are handled by <a href="services.html">Accessibility Services</a>, 246 which use the information in these events to produce supplemental feedback and prompts when users 247 have enabled accessibility services. As of Android 4.0 (API Level 14) and higher, the methods for 248 generating accessibility events have been expanded to provide more detailed information beyond the 249 {@link android.view.accessibility.AccessibilityEventSource} interface introduced in Android 1.6 (API 250 Level 4). The expanded accessibility methods are part of the {@link android.view.View} class as well 251 as the {@link android.view.View.AccessibilityDelegate} class. The methods are as follows:</p> 252 253 <dl> 254 <dt>{@link android.view.View#sendAccessibilityEvent sendAccessibilityEvent()}</dt> 255 <dd>(API Level 4) This method is called when a user takes action on a view. The event is 256 classified with a user action type such as {@link 257 android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED TYPE_VIEW_CLICKED}. You typically do 258 not need to implement this method unless you are creating a custom view.</dd> 259 260 <dt>{@link android.view.View#sendAccessibilityEventUnchecked 261 sendAccessibilityEventUnchecked()}</dt> 262 <dd>(API Level 4) This method is used when the calling code needs to directly control the check 263 for accessibility being enabled on the device ({@link 264 android.view.accessibility.AccessibilityManager#isEnabled AccessibilityManager.isEnabled()}). If 265 you do implement this method, you must assume that the calling method has already checked that 266 accessibility is enabled and the result is {@code true}. You typically do not need to implement this 267 method for a custom view.</dd> 268 269 <dt>{@link android.view.View#dispatchPopulateAccessibilityEvent 270 dispatchPopulateAccessibilityEvent()} </dt> 271 <dd>(API Level 4) The system calls this method when your custom view generates an 272 accessibility event. As of API Level 14, the default implementation of this method calls {@link 273 android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} for this view and 274 then the {@link android.view.View#dispatchPopulateAccessibilityEvent 275 dispatchPopulateAccessibilityEvent()} method for each child of this view. In order to support 276 accessibility services on revisions of Android <em>prior</em> to 4.0 (API Level 14) you 277 <em>must</em> override this method and populate {@link 278 android.view.accessibility.AccessibilityEvent#getText} with descriptive text for your custom 279 view.</dd> 280 281 <dt>{@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()}</dt> 282 <dd>(API Level 14) This method sets the text output of an {@link 283 android.view.accessibility.AccessibilityEvent} for your view. This method is also called if the 284 view is a child of a view which generates an accessibility event. 285 286 <p class="note"><strong>Note:</strong> Modifying additional attributes beyond the text within 287 this method potentially overwrites properties set by other methods. So, while you are able modify 288 attributes of the accessibility event with this method, you should limit these changes 289 to text content only and use the {@link android.view.View#onInitializeAccessibilityEvent 290 onInitializeAccessibilityEvent()} method to modify other properties of the event.</p> 291 292 <p class="note"><strong>Note:</strong> If your implementation of this event calls for completely 293 overiding the output text without allowing other parts of your layout to modify its content, then 294 do not call the super implementation of this method in your code.</p> 295 </dd> 296 297 <dt>{@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()}</dt> 298 <dd>(API Level 14) The system calls this method to obtain additional information about the 299 state of the view, beyond text content. If your custom view provides interactive control beyond a 300 simple {@link android.widget.TextView} or {@link android.widget.Button}, you should override this 301 method and set the additional information about your view into the event using this method, such as 302 password field type, checkbox type or states that provide user interaction or feedback. If you 303 do override this method, you must call its super implementation and then only modify properties 304 that have not been set by the super class.</dd> 305 306 <dt>{@link android.view.View#onInitializeAccessibilityNodeInfo 307 onInitializeAccessibilityNodeInfo()}</dt> 308 <dd>(API Level 14) This method provides accessibility services with information about the state of 309 the view. The default {@link android.view.View} implementation sets a standard set of view 310 properties, but if your custom view provides interactive control beyond a simple {@link 311 android.widget.TextView} or {@link android.widget.Button}, you should override this method and set 312 the additional information about your view into the {@link 313 android.view.accessibility.AccessibilityNodeInfo} object handled by this method.</dd> 314 315 <dt>{@link android.view.ViewGroup#onRequestSendAccessibilityEvent 316 onRequestSendAccessibilityEvent()}</dt> 317 <dd>(API Level 14) The system calls this method when a child of your view has generated an 318 {@link android.view.accessibility.AccessibilityEvent}. This step allows the the parent view to amend 319 the accessibility event with additional information. You should implement this method only if your 320 custom view can have child views and if the parent view can provide context information to the 321 accessibility event that would be useful to accessibility services.</dd> 322 </dl> 323 324 <p>In order to support these accessibility methods for a custom view, you should take one of the 325 following approaches:</p> 326 327 <ul> 328 <li>If your application targets Android 4.0 (API level 14) and higher, override and implement the 329 accessibility methods listed above directly in your custom view class.</li> 330 <li>If your custom view is intended to be compatible with Android 1.6 (API Level 4) and above, add 331 the Android <a href="{@docRoot}tools/extras/support-library.html">Support Library</a>, revision 5 or 332 higher, to your project. Then, within your custom view class, call the 333 {@link android.support.v4.view.ViewCompat#setAccessibilityDelegate 334 ViewCompat.setAccessibilityDelegate()} method to implement the accessibility methods 335 above. For an example of this approach, see the Android Support Library (revision 5 or higher) 336 sample {@code AccessibilityDelegateSupportActivity} in 337 ({@code <sdk>/extras/android/support/v4/samples/Support4Demos/}) 338 </li> 339 </ul> 340 341 <p>In either case, you should implement the following accessibility methods for your custom view 342 class:</p> 343 344 <ul> 345 <li>{@link android.view.View#dispatchPopulateAccessibilityEvent 346 dispatchPopulateAccessibilityEvent()}</li> 347 <li>{@link android.view.View#onPopulateAccessibilityEvent 348 onPopulateAccessibilityEvent()}</li> 349 <li>{@link android.view.View#onInitializeAccessibilityEvent 350 onInitializeAccessibilityEvent()}</li> 351 <li>{@link android.view.View#onInitializeAccessibilityNodeInfo 352 onInitializeAccessibilityNodeInfo()}</li> 353 </ul> 354 355 <p>For more information about implementing these methods, see <a href="#populate-events">Populating 356 Accessibility Events</a>.</p> 357 358 359 <h3 id="send-events">Sending accessibility events</h3> 360 361 <p>Depending on the specifics of your custom view, it may need to send {@link 362 android.view.accessibility.AccessibilityEvent} objects at a different times or for events not 363 handled by the default implementation. The {@link android.view.View} class provides a default 364 implementation for these event types:</p> 365 366 <ul> 367 <li>Starting with API Level 4: 368 <ul> 369 <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED}</li> 370 371 <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}</li> 372 373 <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED}</li> 374 </ul> 375 </li> 376 <li>Starting with API Level 14: 377 <ul> 378 <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED}</li> 379 380 <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}</li> 381 382 <li>{@link android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}</li> 383 </ul> 384 </li> 385 </ul> 386 387 <p class="note"><strong>Note:</strong> Hover events are associated with the Explore by 388 Touch feature, which uses these events as triggers for providing audible prompts for user interface 389 elements.</p> 390 391 <p>In general, you should send an {@link android.view.accessibility.AccessibilityEvent} whenever the 392 content of your custom view changes. For example, if you are implementing a custom slider bar that 393 allows a user to select a numeric value by pressing the left or right arrows, your custom view 394 should emit an event of type {@link 395 android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} whenever the slider 396 value changes. The following sample code demonstrates the use of the {@link 397 android.view.accessibility.AccessibilityEventSource#sendAccessibilityEvent 398 sendAccessibilityEvent()} method to report this event.</p> 399 400 <pre> 401 @Override 402 public boolean onKeyUp (int keyCode, KeyEvent event) { 403 if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { 404 mCurrentValue--; 405 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); 406 return true; 407 } 408 ... 409 } 410 </pre> 411 412 413 <h3 id="populate-events">Populating accessibility events</h3> 414 415 <p>Each {@link android.view.accessibility.AccessibilityEvent} has a set of required properties that 416 describe the current state of the view. These properties include things such as the views class 417 name, content description and checked state. The specific properties required for each event type 418 are described in the {@link android.view.accessibility.AccessibilityEvent} reference documentation. 419 The {@link android.view.View} implementation provides default values for these properties. Many of 420 these values, including the class name and event timestamp, are provided automatically. If you are 421 creating a custom view component, you must provide some information about the content and 422 characteristics of the view. This information may be as simple as a button label, but may also 423 include additional state information that you want to add to the event.</p> 424 425 <p>The minimum requirement for providing information to accessibility services with a custom 426 view is to implement {@link android.view.View#dispatchPopulateAccessibilityEvent 427 dispatchPopulateAccessibilityEvent()}. This method is called by the system to request 428 information for an {@link android.view.accessibility.AccessibilityEvent} and makes your custom 429 view compatible with accessibility services on Android 1.6 (API Level 4) and higher. The 430 following example code demonstrates a basic implementation of this method.</p> 431 432 <pre> 433 @Override 434 public void dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 435 super.dispatchPopulateAccessibilityEvent(event); 436 // Call the super implementation to populate its text to the event, which 437 // calls onPopulateAccessibilityEvent() on API Level 14 and up. 438 439 // In case this is running on a API revision earlier that 14, check 440 // the text content of the event and add an appropriate text 441 // description for this custom view: 442 CharSequence text = getText(); 443 if (!TextUtils.isEmpty(text)) { 444 event.getText().add(text); 445 } 446 } 447 </pre> 448 449 <p>On Android 4.0 (API Level 14) and higher, the {@link 450 android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and 451 {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} 452 methods are the recommended way to populate or modify the information in an {@link 453 android.view.accessibility.AccessibilityEvent}. Use the 454 {@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} method 455 specifically for adding or modifying the text content of the event, which is turned into audible 456 prompts by accessibility services such as TalkBack. Use the 457 {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} method for 458 populating additional information about the event, such as the selection state of the view.</p> 459 460 <p>In addition, you should also implement the 461 {@link android.view.View#onInitializeAccessibilityNodeInfo onInitializeAccessibilityNodeInfo()} 462 method. {@link android.view.accessibility.AccessibilityNodeInfo} objects populated by this method 463 are used by accessibility services to investigate the view hierarchy that generated an accessibility 464 event after receiving that event, to obtain a more detailed context information and provide 465 appropriate feedback to users.</p> 466 467 <p>The example code below shows how override these three methods by using 468 {@link android.support.v4.view.ViewCompat#setAccessibilityDelegate 469 ViewCompat.setAccessibilityDelegate()}. Note that this sample code requires that the Android 470 <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> for API Level 4 (revision 5 471 or higher) is added to your project.</p> 472 473 <pre> 474 ViewCompat.setAccessibilityDelegate(new AccessibilityDelegateCompat() { 475 @Override 476 public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) { 477 super.onPopulateAccessibilityEvent(host, event); 478 // We call the super implementation to populate its text for the 479 // event. Then we add our text not present in a super class. 480 // Very often you only need to add the text for the custom view. 481 CharSequence text = getText(); 482 if (!TextUtils.isEmpty(text)) { 483 event.getText().add(text); 484 } 485 } 486 @Override 487 public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 488 super.onInitializeAccessibilityEvent(host, event); 489 // We call the super implementation to let super classes 490 // set appropriate event properties. Then we add the new property 491 // (checked) which is not supported by a super class. 492 event.setChecked(isChecked()); 493 } 494 @Override 495 public void onInitializeAccessibilityNodeInfo(View host, 496 AccessibilityNodeInfoCompat info) { 497 super.onInitializeAccessibilityNodeInfo(host, info); 498 // We call the super implementation to let super classes set 499 // appropriate info properties. Then we add our properties 500 // (checkable and checked) which are not supported by a super class. 501 info.setCheckable(true); 502 info.setChecked(isChecked()); 503 // Quite often you only need to add the text for the custom view. 504 CharSequence text = getText(); 505 if (!TextUtils.isEmpty(text)) { 506 info.setText(text); 507 } 508 } 509 } 510 </pre> 511 512 <p>On applications targeting Android 4.0 (API Level 14) and higher, these methods can be implemented 513 directly in your custom view class. For another example of this approach, see the Android 514 <a href="{@docRoot}tools/extras/support-library.html">Support Library</a> (revision 5 or higher) sample 515 {@code AccessibilityDelegateSupportActivity} in 516 ({@code <sdk>/extras/android/support/v4/samples/Support4Demos/}).</p> 517 518 <p class="note"><strong>Note:</strong> You may find information on implementing accessibility for 519 custom views written prior to Android 4.0 that describes the use of the 520 {@link android.view.View#dispatchPopulateAccessibilityEvent dispatchPopulateAccessibilityEvent()} 521 method for populating AccessibilityEvents. As of the Android 4.0 release, however, the recommended 522 approach is to use the 523 {@link android.view.View#onPopulateAccessibilityEvent onPopulateAccessibilityEvent()} and 524 {@link android.view.View#onInitializeAccessibilityEvent onInitializeAccessibilityEvent()} 525 methods.</p> 526 527 528 <h2 id="test">Testing Accessibility</h2> 529 530 <p>Testing the accessibility of your application is an important part of ensuring your users have a 531 great experience. You can test the most important parts of accessibility by testing your application 532 with audible feedback enabled and testing navigation within your application using directional 533 controls.</p> 534 535 <h3 id="test-audibles">Testing audible feedback</h3> 536 <p>You can simulate the experience for many users by enabling an accessibility service that speaks 537 as you move around the screen. The Explore by Touch accessibility service, which is available on 538 devices with Android 4.0 and later. The <a 539 href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a> 540 accessibility service, by the <a href="http://code.google.com/p/eyes-free/">Eyes-Free 541 Project</a> comes preinstalled on many Android devices.</p> 542 543 <p>To enable TalkBack on revisions of Android prior to Android 4.0:</p> 544 <ol> 545 <li>Launch the Settings application.</li> 546 <li>Navigate to the <strong>Accessibility</strong> category and select it.</li> 547 <li>Select <strong>Accessibility</strong> to enable it.</li> 548 <li>Select <strong>TalkBack</strong> to enable it.</li> 549 </ol> 550 551 <p class="note"><strong>Note:</strong> If the TalkBack accessibility service is not available, you 552 can install it for free from <a href="http://play.google.com">Google Play</a>.</p> 553 554 <p>To enable Explore by Touch on Android 4.0 and later:</p> 555 <ol> 556 <li>Launch the Settings application.</li> 557 <li>Navigate to the <strong>Accessibility</strong> category and select it.</li> 558 <li>Select the <strong>TalkBack</strong> to enable it.</li> 559 <li>Return to the <strong>Accessibility</strong> category and select <strong>Explore by 560 Touch</strong> to enable it. 561 <p class="note"><strong>Note:</strong> You must turn on TalkBack <em>first</em>, otherwise this 562 option is not available.</p> 563 </li> 564 </ol> 565 566 <h3 id="test-navigation">Testing focus navigation</h3> 567 568 <p>As part of your accessibility testing, you can test navigation of your application using focus, 569 even if your test devices does not have a directional controller. The <a 570 href="{@docRoot}tools/help/emulator.html">Android Emulator</a> provides a 571 simulated directional controller that you can easily use to test navigation. You can also use a 572 software-based directional controller, such as the one provided by the 573 <a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin"> 574 Eyes-Free Keyboard</a> to simulate use of a D-pad.</p> 575