1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v4.view; 18 19import android.graphics.Paint; 20import android.graphics.Rect; 21import android.os.Bundle; 22import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 23import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat; 24import android.view.View; 25import android.view.ViewParent; 26import android.view.accessibility.AccessibilityEvent; 27 28/** 29 * Helper for accessing features in {@link View} introduced after API 30 * level 4 in a backwards compatible fashion. 31 */ 32public class ViewCompat { 33 /** 34 * Always allow a user to over-scroll this view, provided it is a 35 * view that can scroll. 36 */ 37 public static final int OVER_SCROLL_ALWAYS = 0; 38 39 /** 40 * Allow a user to over-scroll this view only if the content is large 41 * enough to meaningfully scroll, provided it is a view that can scroll. 42 */ 43 public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; 44 45 /** 46 * Never allow a user to over-scroll this view. 47 */ 48 public static final int OVER_SCROLL_NEVER = 2; 49 50 private static final long FAKE_FRAME_TIME = 10; 51 52 /** 53 * Automatically determine whether a view is important for accessibility. 54 */ 55 public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000; 56 57 /** 58 * The view is important for accessibility. 59 */ 60 public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001; 61 62 /** 63 * The view is not important for accessibility. 64 */ 65 public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002; 66 67 /** 68 * Indicates that the view does not have a layer. 69 */ 70 public static final int LAYER_TYPE_NONE = 0; 71 72 /** 73 * <p>Indicates that the view has a software layer. A software layer is backed 74 * by a bitmap and causes the view to be rendered using Android's software 75 * rendering pipeline, even if hardware acceleration is enabled.</p> 76 * 77 * <p>Software layers have various usages:</p> 78 * <p>When the application is not using hardware acceleration, a software layer 79 * is useful to apply a specific color filter and/or blending mode and/or 80 * translucency to a view and all its children.</p> 81 * <p>When the application is using hardware acceleration, a software layer 82 * is useful to render drawing primitives not supported by the hardware 83 * accelerated pipeline. It can also be used to cache a complex view tree 84 * into a texture and reduce the complexity of drawing operations. For instance, 85 * when animating a complex view tree with a translation, a software layer can 86 * be used to render the view tree only once.</p> 87 * <p>Software layers should be avoided when the affected view tree updates 88 * often. Every update will require to re-render the software layer, which can 89 * potentially be slow (particularly when hardware acceleration is turned on 90 * since the layer will have to be uploaded into a hardware texture after every 91 * update.)</p> 92 */ 93 public static final int LAYER_TYPE_SOFTWARE = 1; 94 95 /** 96 * <p>Indicates that the view has a hardware layer. A hardware layer is backed 97 * by a hardware specific texture (generally Frame Buffer Objects or FBO on 98 * OpenGL hardware) and causes the view to be rendered using Android's hardware 99 * rendering pipeline, but only if hardware acceleration is turned on for the 100 * view hierarchy. When hardware acceleration is turned off, hardware layers 101 * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p> 102 * 103 * <p>A hardware layer is useful to apply a specific color filter and/or 104 * blending mode and/or translucency to a view and all its children.</p> 105 * <p>A hardware layer can be used to cache a complex view tree into a 106 * texture and reduce the complexity of drawing operations. For instance, 107 * when animating a complex view tree with a translation, a hardware layer can 108 * be used to render the view tree only once.</p> 109 * <p>A hardware layer can also be used to increase the rendering quality when 110 * rotation transformations are applied on a view. It can also be used to 111 * prevent potential clipping issues when applying 3D transforms on a view.</p> 112 */ 113 public static final int LAYER_TYPE_HARDWARE = 2; 114 115 /** 116 * Horizontal layout direction of this view is from Left to Right. 117 */ 118 public static final int LAYOUT_DIRECTION_LTR = 0; 119 120 /** 121 * Horizontal layout direction of this view is from Right to Left. 122 */ 123 public static final int LAYOUT_DIRECTION_RTL = 1; 124 125 /** 126 * Horizontal layout direction of this view is inherited from its parent. 127 * Use with {@link #setLayoutDirection}. 128 */ 129 public static final int LAYOUT_DIRECTION_INHERIT = 2; 130 131 /** 132 * Horizontal layout direction of this view is from deduced from the default language 133 * script for the locale. Use with {@link #setLayoutDirection}. 134 */ 135 public static final int LAYOUT_DIRECTION_LOCALE = 3; 136 137 interface ViewCompatImpl { 138 public boolean canScrollHorizontally(View v, int direction); 139 public boolean canScrollVertically(View v, int direction); 140 public int getOverScrollMode(View v); 141 public void setOverScrollMode(View v, int mode); 142 public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event); 143 public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event); 144 public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info); 145 public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate); 146 public boolean hasTransientState(View view); 147 public void setHasTransientState(View view, boolean hasTransientState); 148 public void postInvalidateOnAnimation(View view); 149 public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom); 150 public void postOnAnimation(View view, Runnable action); 151 public void postOnAnimationDelayed(View view, Runnable action, long delayMillis); 152 public int getImportantForAccessibility(View view); 153 public void setImportantForAccessibility(View view, int mode); 154 public boolean performAccessibilityAction(View view, int action, Bundle arguments); 155 public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view); 156 public void setLayerType(View view, int layerType, Paint paint); 157 public int getLayerType(View view); 158 public int getLabelFor(View view); 159 public void setLabelFor(View view, int id); 160 public void setLayerPaint(View view, Paint paint); 161 public int getLayoutDirection(View view); 162 public void setLayoutDirection(View view, int layoutDirection); 163 public ViewParent getParentForAccessibility(View view); 164 } 165 166 static class BaseViewCompatImpl implements ViewCompatImpl { 167 public boolean canScrollHorizontally(View v, int direction) { 168 return false; 169 } 170 public boolean canScrollVertically(View v, int direction) { 171 return false; 172 } 173 public int getOverScrollMode(View v) { 174 return OVER_SCROLL_NEVER; 175 } 176 public void setOverScrollMode(View v, int mode) { 177 // Do nothing; API doesn't exist 178 } 179 public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) { 180 // Do nothing; API doesn't exist 181 } 182 public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) { 183 // Do nothing; API doesn't exist 184 } 185 public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) { 186 // Do nothing; API doesn't exist 187 } 188 public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) { 189 // Do nothing; API doesn't exist 190 } 191 public boolean hasTransientState(View view) { 192 // A view can't have transient state if transient state wasn't supported. 193 return false; 194 } 195 public void setHasTransientState(View view, boolean hasTransientState) { 196 // Do nothing; API doesn't exist 197 } 198 public void postInvalidateOnAnimation(View view) { 199 view.postInvalidateDelayed(getFrameTime()); 200 } 201 public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) { 202 view.postInvalidateDelayed(getFrameTime(), left, top, right, bottom); 203 } 204 public void postOnAnimation(View view, Runnable action) { 205 view.postDelayed(action, getFrameTime()); 206 } 207 public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) { 208 view.postDelayed(action, getFrameTime() + delayMillis); 209 } 210 long getFrameTime() { 211 return FAKE_FRAME_TIME; 212 } 213 public int getImportantForAccessibility(View view) { 214 return 0; 215 } 216 public void setImportantForAccessibility(View view, int mode) { 217 218 } 219 public boolean performAccessibilityAction(View view, int action, Bundle arguments) { 220 return false; 221 } 222 public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) { 223 return null; 224 } 225 public void setLayerType(View view, int layerType, Paint paint) { 226 // No-op until layers became available (HC) 227 } 228 public int getLayerType(View view) { 229 return LAYER_TYPE_NONE; 230 } 231 public int getLabelFor(View view) { 232 return 0; 233 } 234 public void setLabelFor(View view, int id) { 235 236 } 237 public void setLayerPaint(View view, Paint p) { 238 // No-op until layers became available (HC) 239 } 240 241 @Override 242 public int getLayoutDirection(View view) { 243 return LAYOUT_DIRECTION_LTR; 244 } 245 246 @Override 247 public void setLayoutDirection(View view, int layoutDirection) { 248 // No-op 249 } 250 251 @Override 252 public ViewParent getParentForAccessibility(View view) { 253 return view.getParent(); 254 } 255 } 256 257 static class GBViewCompatImpl extends BaseViewCompatImpl { 258 @Override 259 public int getOverScrollMode(View v) { 260 return ViewCompatGingerbread.getOverScrollMode(v); 261 } 262 @Override 263 public void setOverScrollMode(View v, int mode) { 264 ViewCompatGingerbread.setOverScrollMode(v, mode); 265 } 266 } 267 268 static class HCViewCompatImpl extends GBViewCompatImpl { 269 long getFrameTime() { 270 return ViewCompatHC.getFrameTime(); 271 } 272 @Override public void setLayerType(View view, int layerType, Paint paint) { 273 ViewCompatHC.setLayerType(view, layerType, paint); 274 } 275 @Override public int getLayerType(View view) { 276 return ViewCompatHC.getLayerType(view); 277 } 278 @Override 279 public void setLayerPaint(View view, Paint paint) { 280 // Make sure the paint is correct; this will be cheap if it's the same 281 // instance as was used to call setLayerType earlier. 282 setLayerType(view, getLayerType(view), paint); 283 // This is expensive, but the only way to accomplish this before JB-MR1. 284 view.invalidate(); 285 } 286 } 287 288 static class ICSViewCompatImpl extends HCViewCompatImpl { 289 @Override 290 public boolean canScrollHorizontally(View v, int direction) { 291 return ViewCompatICS.canScrollHorizontally(v, direction); 292 } 293 @Override 294 public boolean canScrollVertically(View v, int direction) { 295 return ViewCompatICS.canScrollVertically(v, direction); 296 } 297 @Override 298 public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) { 299 ViewCompatICS.onPopulateAccessibilityEvent(v, event); 300 } 301 @Override 302 public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) { 303 ViewCompatICS.onInitializeAccessibilityEvent(v, event); 304 } 305 @Override 306 public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) { 307 ViewCompatICS.onInitializeAccessibilityNodeInfo(v, info.getInfo()); 308 } 309 @Override 310 public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) { 311 ViewCompatICS.setAccessibilityDelegate(v, delegate.getBridge()); 312 } 313 } 314 315 static class JBViewCompatImpl extends ICSViewCompatImpl { 316 @Override 317 public boolean hasTransientState(View view) { 318 return ViewCompatJB.hasTransientState(view); 319 } 320 @Override 321 public void setHasTransientState(View view, boolean hasTransientState) { 322 ViewCompatJB.setHasTransientState(view, hasTransientState); 323 } 324 @Override 325 public void postInvalidateOnAnimation(View view) { 326 ViewCompatJB.postInvalidateOnAnimation(view); 327 } 328 @Override 329 public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) { 330 ViewCompatJB.postInvalidateOnAnimation(view, left, top, right, bottom); 331 } 332 @Override 333 public void postOnAnimation(View view, Runnable action) { 334 ViewCompatJB.postOnAnimation(view, action); 335 } 336 @Override 337 public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) { 338 ViewCompatJB.postOnAnimationDelayed(view, action, delayMillis); 339 } 340 @Override 341 public int getImportantForAccessibility(View view) { 342 return ViewCompatJB.getImportantForAccessibility(view); 343 } 344 @Override 345 public void setImportantForAccessibility(View view, int mode) { 346 ViewCompatJB.setImportantForAccessibility(view, mode); 347 } 348 @Override 349 public boolean performAccessibilityAction(View view, int action, Bundle arguments) { 350 return ViewCompatJB.performAccessibilityAction(view, action, arguments); 351 } 352 @Override 353 public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) { 354 Object compat = ViewCompatJB.getAccessibilityNodeProvider(view); 355 if (compat != null) { 356 return new AccessibilityNodeProviderCompat(compat); 357 } 358 return null; 359 } 360 361 @Override 362 public ViewParent getParentForAccessibility(View view) { 363 return ViewCompatJB.getParentForAccessibility(view); 364 } 365 } 366 367 static class JbMr1ViewCompatImpl extends JBViewCompatImpl { 368 369 @Override 370 public int getLabelFor(View view) { 371 return ViewCompatJellybeanMr1.getLabelFor(view); 372 } 373 374 @Override 375 public void setLabelFor(View view, int id) { 376 ViewCompatJellybeanMr1.setLabelFor(view, id); 377 } 378 379 @Override 380 public void setLayerPaint(View view, Paint paint) { 381 ViewCompatJellybeanMr1.setLayerPaint(view, paint); 382 } 383 384 @Override 385 public int getLayoutDirection(View view) { 386 return ViewCompatJellybeanMr1.getLayoutDirection(view); 387 } 388 389 @Override 390 public void setLayoutDirection(View view, int layoutDirection) { 391 ViewCompatJellybeanMr1.setLayoutDirection(view, layoutDirection); 392 } 393 } 394 395 static final ViewCompatImpl IMPL; 396 static { 397 final int version = android.os.Build.VERSION.SDK_INT; 398 if (version >= 17) { 399 IMPL = new JbMr1ViewCompatImpl(); 400 } else if (version >= 16) { 401 IMPL = new JBViewCompatImpl(); 402 } else if (version >= 14) { 403 IMPL = new ICSViewCompatImpl(); 404 } else if (version >= 11) { 405 IMPL = new HCViewCompatImpl(); 406 } else if (version >= 9) { 407 IMPL = new GBViewCompatImpl(); 408 } else { 409 IMPL = new BaseViewCompatImpl(); 410 } 411 } 412 413 /** 414 * Check if this view can be scrolled horizontally in a certain direction. 415 * 416 * @param v The View against which to invoke the method. 417 * @param direction Negative to check scrolling left, positive to check scrolling right. 418 * @return true if this view can be scrolled in the specified direction, false otherwise. 419 */ 420 public static boolean canScrollHorizontally(View v, int direction) { 421 return IMPL.canScrollHorizontally(v, direction); 422 } 423 424 /** 425 * Check if this view can be scrolled vertically in a certain direction. 426 * 427 * @param v The View against which to invoke the method. 428 * @param direction Negative to check scrolling up, positive to check scrolling down. 429 * @return true if this view can be scrolled in the specified direction, false otherwise. 430 */ 431 public static boolean canScrollVertically(View v, int direction) { 432 return IMPL.canScrollVertically(v, direction); 433 } 434 435 /** 436 * Returns the over-scroll mode for this view. The result will be 437 * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS} 438 * (allow over-scrolling only if the view content is larger than the container), 439 * or {@link #OVER_SCROLL_NEVER}. 440 * 441 * @param v The View against which to invoke the method. 442 * @return This view's over-scroll mode. 443 */ 444 public static int getOverScrollMode(View v) { 445 return IMPL.getOverScrollMode(v); 446 } 447 448 /** 449 * Set the over-scroll mode for this view. Valid over-scroll modes are 450 * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS} 451 * (allow over-scrolling only if the view content is larger than the container), 452 * or {@link #OVER_SCROLL_NEVER}. 453 * 454 * Setting the over-scroll mode of a view will have an effect only if the 455 * view is capable of scrolling. 456 * 457 * @param v The View against which to invoke the method. 458 * @param overScrollMode The new over-scroll mode for this view. 459 */ 460 public static void setOverScrollMode(View v, int overScrollMode) { 461 IMPL.setOverScrollMode(v, overScrollMode); 462 } 463 464 /** 465 * Called from {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} 466 * giving a chance to this View to populate the accessibility event with its 467 * text content. While this method is free to modify event 468 * attributes other than text content, doing so should normally be performed in 469 * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)}. 470 * <p> 471 * Example: Adding formatted date string to an accessibility event in addition 472 * to the text added by the super implementation: 473 * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 474 * super.onPopulateAccessibilityEvent(event); 475 * final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY; 476 * String selectedDateUtterance = DateUtils.formatDateTime(mContext, 477 * mCurrentDate.getTimeInMillis(), flags); 478 * event.getText().add(selectedDateUtterance); 479 * }</pre> 480 * <p> 481 * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling 482 * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its 483 * {@link android.view.View.AccessibilityDelegate#onPopulateAccessibilityEvent(View, 484 * AccessibilityEvent)} 485 * is responsible for handling this call. 486 * </p> 487 * <p class="note"><strong>Note:</strong> Always call the super implementation before adding 488 * information to the event, in case the default implementation has basic information to add. 489 * </p> 490 * 491 * @param v The View against which to invoke the method. 492 * @param event The accessibility event which to populate. 493 * 494 * @see View#sendAccessibilityEvent(int) 495 * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) 496 */ 497 public static void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) { 498 IMPL.onPopulateAccessibilityEvent(v, event); 499 } 500 501 /** 502 * Initializes an {@link AccessibilityEvent} with information about 503 * this View which is the event source. In other words, the source of 504 * an accessibility event is the view whose state change triggered firing 505 * the event. 506 * <p> 507 * Example: Setting the password property of an event in addition 508 * to properties set by the super implementation: 509 * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 510 * super.onInitializeAccessibilityEvent(event); 511 * event.setPassword(true); 512 * }</pre> 513 * <p> 514 * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling 515 * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its 516 * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityEvent(View, 517 * AccessibilityEvent)} 518 * is responsible for handling this call. 519 * </p> 520 * <p class="note"><strong>Note:</strong> Always call the super implementation before adding 521 * information to the event, in case the default implementation has basic information to add. 522 * </p> 523 * 524 * @param v The View against which to invoke the method. 525 * @param event The event to initialize. 526 * 527 * @see View#sendAccessibilityEvent(int) 528 * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) 529 */ 530 public static void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) { 531 IMPL.onInitializeAccessibilityEvent(v, event); 532 } 533 534 /** 535 * Initializes an {@link android.view.accessibility.AccessibilityNodeInfo} with information 536 * about this view. The base implementation sets: 537 * <ul> 538 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setParent(View)},</li> 539 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInParent(Rect)},</li> 540 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li> 541 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setPackageName(CharSequence)},</li> 542 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClassName(CharSequence)},</li> 543 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setContentDescription(CharSequence)},</li> 544 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setEnabled(boolean)},</li> 545 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClickable(boolean)},</li> 546 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocusable(boolean)},</li> 547 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocused(boolean)},</li> 548 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setLongClickable(boolean)},</li> 549 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setSelected(boolean)},</li> 550 * </ul> 551 * <p> 552 * Subclasses should override this method, call the super implementation, 553 * and set additional attributes. 554 * </p> 555 * <p> 556 * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling 557 * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its 558 * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, 559 * android.view.accessibility.AccessibilityNodeInfo)} 560 * is responsible for handling this call. 561 * </p> 562 * 563 * @param v The View against which to invoke the method. 564 * @param info The instance to initialize. 565 */ 566 public static void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) { 567 IMPL.onInitializeAccessibilityNodeInfo(v, info); 568 } 569 570 /** 571 * Sets a delegate for implementing accessibility support via compositon as 572 * opposed to inheritance. The delegate's primary use is for implementing 573 * backwards compatible widgets. For more details see 574 * {@link android.view.View.AccessibilityDelegate}. 575 * 576 * @param v The View against which to invoke the method. 577 * @param delegate The delegate instance. 578 * 579 * @see android.view.View.AccessibilityDelegate 580 */ 581 public static void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) { 582 IMPL.setAccessibilityDelegate(v, delegate); 583 } 584 585 /** 586 * Indicates whether the view is currently tracking transient state that the 587 * app should not need to concern itself with saving and restoring, but that 588 * the framework should take special note to preserve when possible. 589 * 590 * @param view View to check for transient state 591 * @return true if the view has transient state 592 */ 593 public static boolean hasTransientState(View view) { 594 return IMPL.hasTransientState(view); 595 } 596 597 /** 598 * Set whether this view is currently tracking transient state that the 599 * framework should attempt to preserve when possible. 600 * 601 * @param view View tracking transient state 602 * @param hasTransientState true if this view has transient state 603 */ 604 public static void setHasTransientState(View view, boolean hasTransientState) { 605 IMPL.setHasTransientState(view, hasTransientState); 606 } 607 608 /** 609 * <p>Cause an invalidate to happen on the next animation time step, typically the 610 * next display frame.</p> 611 * 612 * <p>This method can be invoked from outside of the UI thread 613 * only when this View is attached to a window.</p> 614 * 615 * @param view View to invalidate 616 */ 617 public static void postInvalidateOnAnimation(View view) { 618 IMPL.postInvalidateOnAnimation(view); 619 } 620 621 /** 622 * <p>Cause an invalidate of the specified area to happen on the next animation 623 * time step, typically the next display frame.</p> 624 * 625 * <p>This method can be invoked from outside of the UI thread 626 * only when this View is attached to a window.</p> 627 * 628 * @param view View to invalidate 629 * @param left The left coordinate of the rectangle to invalidate. 630 * @param top The top coordinate of the rectangle to invalidate. 631 * @param right The right coordinate of the rectangle to invalidate. 632 * @param bottom The bottom coordinate of the rectangle to invalidate. 633 */ 634 public static void postInvalidateOnAnimation(View view, int left, int top, 635 int right, int bottom) { 636 IMPL.postInvalidateOnAnimation(view, left, top, right, bottom); 637 } 638 639 /** 640 * <p>Causes the Runnable to execute on the next animation time step. 641 * The runnable will be run on the user interface thread.</p> 642 * 643 * <p>This method can be invoked from outside of the UI thread 644 * only when this View is attached to a window.</p> 645 * 646 * @param view View to post this Runnable to 647 * @param action The Runnable that will be executed. 648 */ 649 public static void postOnAnimation(View view, Runnable action) { 650 IMPL.postOnAnimation(view, action); 651 } 652 653 /** 654 * <p>Causes the Runnable to execute on the next animation time step, 655 * after the specified amount of time elapses. 656 * The runnable will be run on the user interface thread.</p> 657 * 658 * <p>This method can be invoked from outside of the UI thread 659 * only when this View is attached to a window.</p> 660 * 661 * @param view The view to post this Runnable to 662 * @param action The Runnable that will be executed. 663 * @param delayMillis The delay (in milliseconds) until the Runnable 664 * will be executed. 665 */ 666 public static void postOnAnimationDelayed(View view, Runnable action, long delayMillis) { 667 IMPL.postOnAnimationDelayed(view, action, delayMillis); 668 } 669 670 /** 671 * Gets the mode for determining whether this View is important for accessibility 672 * which is if it fires accessibility events and if it is reported to 673 * accessibility services that query the screen. 674 * 675 * @param view The view whose property to get. 676 * @return The mode for determining whether a View is important for accessibility. 677 * 678 * @see #IMPORTANT_FOR_ACCESSIBILITY_YES 679 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO 680 * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO 681 */ 682 public static int getImportantForAccessibility(View view) { 683 return IMPL.getImportantForAccessibility(view); 684 } 685 686 /** 687 * Sets how to determine whether this view is important for accessibility 688 * which is if it fires accessibility events and if it is reported to 689 * accessibility services that query the screen. 690 * 691 * @param view The view whose property to set. 692 * @param mode How to determine whether this view is important for accessibility. 693 * 694 * @see #IMPORTANT_FOR_ACCESSIBILITY_YES 695 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO 696 * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO 697 */ 698 public static void setImportantForAccessibility(View view, int mode) { 699 IMPL.setImportantForAccessibility(view, mode); 700 } 701 702 /** 703 * Performs the specified accessibility action on the view. For 704 * possible accessibility actions look at {@link AccessibilityNodeInfoCompat}. 705 * <p> 706 * If an {@link AccessibilityDelegateCompat} has been specified via calling 707 * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its 708 * {@link AccessibilityDelegateCompat#performAccessibilityAction(View, int, Bundle)} 709 * is responsible for handling this call. 710 * </p> 711 * 712 * @param action The action to perform. 713 * @param arguments Optional action arguments. 714 * @return Whether the action was performed. 715 */ 716 public static boolean performAccessibilityAction(View view, int action, Bundle arguments) { 717 return IMPL.performAccessibilityAction(view, action, arguments); 718 } 719 720 /** 721 * Gets the provider for managing a virtual view hierarchy rooted at this View 722 * and reported to {@link android.accessibilityservice.AccessibilityService}s 723 * that explore the window content. 724 * <p> 725 * If this method returns an instance, this instance is responsible for managing 726 * {@link AccessibilityNodeInfoCompat}s describing the virtual sub-tree rooted at 727 * this View including the one representing the View itself. Similarly the returned 728 * instance is responsible for performing accessibility actions on any virtual 729 * view or the root view itself. 730 * </p> 731 * <p> 732 * If an {@link AccessibilityDelegateCompat} has been specified via calling 733 * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat) its 734 * {@link AccessibilityDelegateCompat#getAccessibilityNodeProvider(View)} 735 * is responsible for handling this call. 736 * </p> 737 * 738 * @param view The view whose property to get. 739 * @return The provider. 740 * 741 * @see AccessibilityNodeProviderCompat 742 */ 743 public static AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) { 744 return IMPL.getAccessibilityNodeProvider(view); 745 } 746 747 /** 748 * <p>Specifies the type of layer backing this view. The layer can be 749 * {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or 750 * {@link #LAYER_TYPE_HARDWARE hardware}.</p> 751 * 752 * <p>A layer is associated with an optional {@link android.graphics.Paint} 753 * instance that controls how the layer is composed on screen. The following 754 * properties of the paint are taken into account when composing the layer:</p> 755 * <ul> 756 * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li> 757 * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li> 758 * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li> 759 * </ul> 760 * 761 * <p>If this view has an alpha value set to < 1.0 by calling 762 * setAlpha(float), the alpha value of the layer's paint is replaced by 763 * this view's alpha value. Calling setAlpha(float) is therefore 764 * equivalent to setting a hardware layer on this view and providing a paint with 765 * the desired alpha value.<p> 766 * 767 * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled}, 768 * {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware} 769 * for more information on when and how to use layers.</p> 770 * 771 * @param layerType The ype of layer to use with this view, must be one of 772 * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or 773 * {@link #LAYER_TYPE_HARDWARE} 774 * @param paint The paint used to compose the layer. This argument is optional 775 * and can be null. It is ignored when the layer type is 776 * {@link #LAYER_TYPE_NONE} 777 * 778 * @param view View to set the layer type for 779 * @param layerType The type of layer to use with this view, must be one of 780 * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or 781 * {@link #LAYER_TYPE_HARDWARE} 782 * @param paint The paint used to compose the layer. This argument is optional 783 * and can be null. It is ignored when the layer type is 784 * {@link #LAYER_TYPE_NONE} 785 */ 786 public static void setLayerType(View view, int layerType, Paint paint) { 787 IMPL.setLayerType(view, layerType, paint); 788 } 789 790 /** 791 * Indicates what type of layer is currently associated with this view. By default 792 * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}. 793 * Refer to the documentation of 794 * {@link #setLayerType(android.view.View, int, android.graphics.Paint)} 795 * for more information on the different types of layers. 796 * 797 * @param view The view to fetch the layer type from 798 * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or 799 * {@link #LAYER_TYPE_HARDWARE} 800 * 801 * @see #setLayerType(android.view.View, int, android.graphics.Paint) 802 * @see #LAYER_TYPE_NONE 803 * @see #LAYER_TYPE_SOFTWARE 804 * @see #LAYER_TYPE_HARDWARE 805 */ 806 public static int getLayerType(View view) { 807 return IMPL.getLayerType(view); 808 } 809 810 /** 811 * Gets the id of a view for which a given view serves as a label for 812 * accessibility purposes. 813 * 814 * @param view The view on which to invoke the corresponding method. 815 * @return The labeled view id. 816 */ 817 public static int getLabelFor(View view) { 818 return IMPL.getLabelFor(view); 819 } 820 821 /** 822 * Sets the id of a view for which a given view serves as a label for 823 * accessibility purposes. 824 * 825 * @param view The view on which to invoke the corresponding method. 826 * @param labeledId The labeled view id. 827 */ 828 public static void setLabelFor(View view, int labeledId) { 829 IMPL.setLabelFor(view, labeledId); 830 } 831 832 /** 833 * Updates the {@link Paint} object used with the current layer (used only if the current 834 * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint 835 * provided to {@link #setLayerType(android.view.View, int, android.graphics.Paint)} 836 * will be used the next time the View is redrawn, but 837 * {@link #setLayerPaint(android.view.View, android.graphics.Paint)} 838 * must be called to ensure that the view gets redrawn immediately. 839 * 840 * <p>A layer is associated with an optional {@link android.graphics.Paint} 841 * instance that controls how the layer is composed on screen. The following 842 * properties of the paint are taken into account when composing the layer:</p> 843 * <ul> 844 * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li> 845 * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li> 846 * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li> 847 * </ul> 848 * 849 * <p>If this view has an alpha value set to < 1.0 by calling 850 * View#setAlpha(float), the alpha value of the layer's paint is replaced by 851 * this view's alpha value. Calling View#setAlpha(float) is therefore 852 * equivalent to setting a hardware layer on this view and providing a paint with 853 * the desired alpha value.</p> 854 * 855 * @param view View to set a layer paint for 856 * @param paint The paint used to compose the layer. This argument is optional 857 * and can be null. It is ignored when the layer type is 858 * {@link #LAYER_TYPE_NONE} 859 * 860 * @see #setLayerType(View, int, android.graphics.Paint) 861 */ 862 public static void setLayerPaint(View view, Paint paint) { 863 IMPL.setLayerPaint(view, paint); 864 } 865 866 /** 867 * Returns the resolved layout direction for this view. 868 * 869 * @param view View to get layout direction for 870 * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns 871 * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL. 872 * 873 * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version 874 * is lower than Jellybean MR1 (API 17) 875 */ 876 public static int getLayoutDirection(View view) { 877 return IMPL.getLayoutDirection(view); 878 } 879 880 /** 881 * Set the layout direction for this view. This will propagate a reset of layout direction 882 * resolution to the view's children and resolve layout direction for this view. 883 * 884 * @param view View to set layout direction for 885 * @param layoutDirection the layout direction to set. Should be one of: 886 * 887 * {@link #LAYOUT_DIRECTION_LTR}, 888 * {@link #LAYOUT_DIRECTION_RTL}, 889 * {@link #LAYOUT_DIRECTION_INHERIT}, 890 * {@link #LAYOUT_DIRECTION_LOCALE}. 891 * 892 * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution 893 * proceeds up the parent chain of the view to get the value. If there is no parent, then it 894 * will return the default {@link #LAYOUT_DIRECTION_LTR}. 895 */ 896 public static void setLayoutDirection(View view, int layoutDirection) { 897 IMPL.setLayoutDirection(view, layoutDirection); 898 } 899 900 /** 901 * Gets the parent for accessibility purposes. Note that the parent for 902 * accessibility is not necessary the immediate parent. It is the first 903 * predecessor that is important for accessibility. 904 * 905 * @param view View to retrieve parent for 906 * @return The parent for use in accessibility inspection 907 */ 908 public static ViewParent getParentForAccessibility(View view) { 909 return IMPL.getParentForAccessibility(view); 910 } 911} 912