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