ViewCompat.java revision a972a99dddff41d5f54a18629185a7290a63d1f9
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 static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20 21import android.animation.ValueAnimator; 22import android.support.annotation.RequiresApi; 23import android.content.ClipData; 24import android.content.Context; 25import android.content.res.ColorStateList; 26import android.graphics.Matrix; 27import android.graphics.Paint; 28import android.graphics.PorterDuff; 29import android.graphics.Rect; 30import android.graphics.drawable.Drawable; 31import android.os.Build; 32import android.os.Bundle; 33import android.support.annotation.FloatRange; 34import android.support.annotation.IdRes; 35import android.support.annotation.IntDef; 36import android.support.annotation.NonNull; 37import android.support.annotation.Nullable; 38import android.support.annotation.RestrictTo; 39import android.support.v4.os.BuildCompat; 40import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 41import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat; 42import android.util.Log; 43import android.view.Display; 44import android.view.MotionEvent; 45import android.view.PointerIcon; 46import android.view.VelocityTracker; 47import android.view.View; 48import android.view.ViewConfiguration; 49import android.view.ViewGroup; 50import android.view.ViewParent; 51import android.view.WindowInsets; 52import android.view.WindowManager; 53import android.view.accessibility.AccessibilityEvent; 54import android.view.accessibility.AccessibilityNodeProvider; 55 56import java.lang.annotation.Retention; 57import java.lang.annotation.RetentionPolicy; 58import java.lang.reflect.Field; 59import java.lang.reflect.InvocationTargetException; 60import java.lang.reflect.Method; 61import java.util.WeakHashMap; 62 63/** 64 * Helper for accessing features in {@link View} introduced after API 65 * level 4 in a backwards compatible fashion. 66 */ 67public class ViewCompat { 68 private static final String TAG = "ViewCompat"; 69 70 /** @hide */ 71 @RestrictTo(LIBRARY_GROUP) 72 @IntDef({View.FOCUS_LEFT, View.FOCUS_UP, View.FOCUS_RIGHT, View.FOCUS_DOWN, 73 View.FOCUS_FORWARD, View.FOCUS_BACKWARD}) 74 @Retention(RetentionPolicy.SOURCE) 75 public @interface FocusDirection {} 76 77 /** @hide */ 78 @RestrictTo(LIBRARY_GROUP) 79 @IntDef({View.FOCUS_LEFT, View.FOCUS_UP, View.FOCUS_RIGHT, View.FOCUS_DOWN}) 80 @Retention(RetentionPolicy.SOURCE) 81 public @interface FocusRealDirection {} 82 83 /** @hide */ 84 @RestrictTo(LIBRARY_GROUP) 85 @IntDef({View.FOCUS_FORWARD, View.FOCUS_BACKWARD}) 86 @Retention(RetentionPolicy.SOURCE) 87 public @interface FocusRelativeDirection {} 88 89 @IntDef({OVER_SCROLL_ALWAYS, OVER_SCROLL_IF_CONTENT_SCROLLS, OVER_SCROLL_NEVER}) 90 @Retention(RetentionPolicy.SOURCE) 91 private @interface OverScroll {} 92 93 /** 94 * Always allow a user to over-scroll this view, provided it is a 95 * view that can scroll. 96 * @deprecated Use {@link View#OVER_SCROLL_ALWAYS} directly. This constant will be removed in 97 * a future release. 98 */ 99 @Deprecated 100 public static final int OVER_SCROLL_ALWAYS = 0; 101 102 /** 103 * Allow a user to over-scroll this view only if the content is large 104 * enough to meaningfully scroll, provided it is a view that can scroll. 105 * @deprecated Use {@link View#OVER_SCROLL_IF_CONTENT_SCROLLS} directly. This constant will be 106 * removed in a future release. 107 */ 108 @Deprecated 109 public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; 110 111 /** 112 * Never allow a user to over-scroll this view. 113 * @deprecated Use {@link View#OVER_SCROLL_NEVER} directly. This constant will be removed in 114 * a future release. 115 */ 116 @Deprecated 117 public static final int OVER_SCROLL_NEVER = 2; 118 119 @IntDef({ 120 IMPORTANT_FOR_ACCESSIBILITY_AUTO, 121 IMPORTANT_FOR_ACCESSIBILITY_YES, 122 IMPORTANT_FOR_ACCESSIBILITY_NO, 123 IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS 124 }) 125 @Retention(RetentionPolicy.SOURCE) 126 private @interface ImportantForAccessibility {} 127 128 /** 129 * Automatically determine whether a view is important for accessibility. 130 */ 131 public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000; 132 133 /** 134 * The view is important for accessibility. 135 */ 136 public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001; 137 138 /** 139 * The view is not important for accessibility. 140 */ 141 public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002; 142 143 /** 144 * The view is not important for accessibility, nor are any of its 145 * descendant views. 146 */ 147 public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004; 148 149 @IntDef({ 150 ACCESSIBILITY_LIVE_REGION_NONE, 151 ACCESSIBILITY_LIVE_REGION_POLITE, 152 ACCESSIBILITY_LIVE_REGION_ASSERTIVE 153 }) 154 @Retention(RetentionPolicy.SOURCE) 155 private @interface AccessibilityLiveRegion {} 156 157 /** 158 * Live region mode specifying that accessibility services should not 159 * automatically announce changes to this view. This is the default live 160 * region mode for most views. 161 * <p> 162 * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}. 163 */ 164 public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000; 165 166 /** 167 * Live region mode specifying that accessibility services should announce 168 * changes to this view. 169 * <p> 170 * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}. 171 */ 172 public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001; 173 174 /** 175 * Live region mode specifying that accessibility services should interrupt 176 * ongoing speech to immediately announce changes to this view. 177 * <p> 178 * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}. 179 */ 180 public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002; 181 182 @IntDef({View.LAYER_TYPE_NONE, View.LAYER_TYPE_SOFTWARE, View.LAYER_TYPE_HARDWARE}) 183 @Retention(RetentionPolicy.SOURCE) 184 private @interface LayerType {} 185 186 /** 187 * Indicates that the view does not have a layer. 188 * 189 * @deprecated Use {@link View#LAYER_TYPE_NONE} directly. 190 */ 191 @Deprecated 192 public static final int LAYER_TYPE_NONE = 0; 193 194 /** 195 * <p>Indicates that the view has a software layer. A software layer is backed 196 * by a bitmap and causes the view to be rendered using Android's software 197 * rendering pipeline, even if hardware acceleration is enabled.</p> 198 * 199 * <p>Software layers have various usages:</p> 200 * <p>When the application is not using hardware acceleration, a software layer 201 * is useful to apply a specific color filter and/or blending mode and/or 202 * translucency to a view and all its children.</p> 203 * <p>When the application is using hardware acceleration, a software layer 204 * is useful to render drawing primitives not supported by the hardware 205 * accelerated pipeline. It can also be used to cache a complex view tree 206 * into a texture and reduce the complexity of drawing operations. For instance, 207 * when animating a complex view tree with a translation, a software layer can 208 * be used to render the view tree only once.</p> 209 * <p>Software layers should be avoided when the affected view tree updates 210 * often. Every update will require to re-render the software layer, which can 211 * potentially be slow (particularly when hardware acceleration is turned on 212 * since the layer will have to be uploaded into a hardware texture after every 213 * update.)</p> 214 * 215 * @deprecated Use {@link View#LAYER_TYPE_SOFTWARE} directly. 216 */ 217 @Deprecated 218 public static final int LAYER_TYPE_SOFTWARE = 1; 219 220 /** 221 * <p>Indicates that the view has a hardware layer. A hardware layer is backed 222 * by a hardware specific texture (generally Frame Buffer Objects or FBO on 223 * OpenGL hardware) and causes the view to be rendered using Android's hardware 224 * rendering pipeline, but only if hardware acceleration is turned on for the 225 * view hierarchy. When hardware acceleration is turned off, hardware layers 226 * behave exactly as {@link View#LAYER_TYPE_SOFTWARE software layers}.</p> 227 * 228 * <p>A hardware layer is useful to apply a specific color filter and/or 229 * blending mode and/or translucency to a view and all its children.</p> 230 * <p>A hardware layer can be used to cache a complex view tree into a 231 * texture and reduce the complexity of drawing operations. For instance, 232 * when animating a complex view tree with a translation, a hardware layer can 233 * be used to render the view tree only once.</p> 234 * <p>A hardware layer can also be used to increase the rendering quality when 235 * rotation transformations are applied on a view. It can also be used to 236 * prevent potential clipping issues when applying 3D transforms on a view.</p> 237 * 238 * @deprecated Use {@link View#LAYER_TYPE_HARDWARE} directly. 239 */ 240 @Deprecated 241 public static final int LAYER_TYPE_HARDWARE = 2; 242 243 @IntDef({ 244 LAYOUT_DIRECTION_LTR, 245 LAYOUT_DIRECTION_RTL, 246 LAYOUT_DIRECTION_INHERIT, 247 LAYOUT_DIRECTION_LOCALE}) 248 @Retention(RetentionPolicy.SOURCE) 249 private @interface LayoutDirectionMode {} 250 251 @IntDef({ 252 LAYOUT_DIRECTION_LTR, 253 LAYOUT_DIRECTION_RTL 254 }) 255 @Retention(RetentionPolicy.SOURCE) 256 private @interface ResolvedLayoutDirectionMode {} 257 258 /** 259 * Horizontal layout direction of this view is from Left to Right. 260 */ 261 public static final int LAYOUT_DIRECTION_LTR = 0; 262 263 /** 264 * Horizontal layout direction of this view is from Right to Left. 265 */ 266 public static final int LAYOUT_DIRECTION_RTL = 1; 267 268 /** 269 * Horizontal layout direction of this view is inherited from its parent. 270 * Use with {@link #setLayoutDirection}. 271 */ 272 public static final int LAYOUT_DIRECTION_INHERIT = 2; 273 274 /** 275 * Horizontal layout direction of this view is from deduced from the default language 276 * script for the locale. Use with {@link #setLayoutDirection}. 277 */ 278 public static final int LAYOUT_DIRECTION_LOCALE = 3; 279 280 /** 281 * Bits of {@link #getMeasuredWidthAndState} and 282 * {@link #getMeasuredWidthAndState} that provide the actual measured size. 283 * 284 * @deprecated Use {@link View#MEASURED_SIZE_MASK} directly. 285 */ 286 @Deprecated 287 public static final int MEASURED_SIZE_MASK = 0x00ffffff; 288 289 /** 290 * Bits of {@link #getMeasuredWidthAndState} and 291 * {@link #getMeasuredWidthAndState} that provide the additional state bits. 292 * 293 * @deprecated Use {@link View#MEASURED_STATE_MASK} directly. 294 */ 295 @Deprecated 296 public static final int MEASURED_STATE_MASK = 0xff000000; 297 298 /** 299 * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits 300 * for functions that combine both width and height into a single int, 301 * such as {@link #getMeasuredState} and the childState argument of 302 * {@link #resolveSizeAndState(int, int, int)}. 303 * 304 * @deprecated Use {@link View#MEASURED_HEIGHT_STATE_SHIFT} directly. 305 */ 306 @Deprecated 307 public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; 308 309 /** 310 * Bit of {@link #getMeasuredWidthAndState} and 311 * {@link #getMeasuredWidthAndState} that indicates the measured size 312 * is smaller that the space the view would like to have. 313 * 314 * @deprecated Use {@link View#MEASURED_STATE_TOO_SMALL} directly. 315 */ 316 @Deprecated 317 public static final int MEASURED_STATE_TOO_SMALL = 0x01000000; 318 319 /** 320 * Indicates no axis of view scrolling. 321 */ 322 public static final int SCROLL_AXIS_NONE = 0; 323 324 /** 325 * Indicates scrolling along the horizontal axis. 326 */ 327 public static final int SCROLL_AXIS_HORIZONTAL = 1 << 0; 328 329 /** 330 * Indicates scrolling along the vertical axis. 331 */ 332 public static final int SCROLL_AXIS_VERTICAL = 1 << 1; 333 334 /** @hide */ 335 @RestrictTo(LIBRARY_GROUP) 336 @Retention(RetentionPolicy.SOURCE) 337 @IntDef(flag = true, 338 value = { 339 SCROLL_INDICATOR_TOP, 340 SCROLL_INDICATOR_BOTTOM, 341 SCROLL_INDICATOR_LEFT, 342 SCROLL_INDICATOR_RIGHT, 343 SCROLL_INDICATOR_START, 344 SCROLL_INDICATOR_END, 345 }) 346 public @interface ScrollIndicators {} 347 348 /** 349 * Scroll indicator direction for the top edge of the view. 350 * 351 * @see #setScrollIndicators(View, int) 352 * @see #setScrollIndicators(View, int, int) 353 * @see #getScrollIndicators(View) 354 */ 355 public static final int SCROLL_INDICATOR_TOP = 0x1; 356 357 /** 358 * Scroll indicator direction for the bottom edge of the view. 359 * 360 * @see #setScrollIndicators(View, int) 361 * @see #setScrollIndicators(View, int, int) 362 * @see #getScrollIndicators(View) 363 */ 364 public static final int SCROLL_INDICATOR_BOTTOM = 0x2; 365 366 /** 367 * Scroll indicator direction for the left edge of the view. 368 * 369 * @see #setScrollIndicators(View, int) 370 * @see #setScrollIndicators(View, int, int) 371 * @see #getScrollIndicators(View) 372 */ 373 public static final int SCROLL_INDICATOR_LEFT = 0x4; 374 375 /** 376 * Scroll indicator direction for the right edge of the view. 377 * 378 * @see #setScrollIndicators(View, int) 379 * @see #setScrollIndicators(View, int, int) 380 * @see #getScrollIndicators(View) 381 */ 382 public static final int SCROLL_INDICATOR_RIGHT = 0x8; 383 384 /** 385 * Scroll indicator direction for the starting edge of the view. 386 * 387 * @see #setScrollIndicators(View, int) 388 * @see #setScrollIndicators(View, int, int) 389 * @see #getScrollIndicators(View) 390 */ 391 public static final int SCROLL_INDICATOR_START = 0x10; 392 393 /** 394 * Scroll indicator direction for the ending edge of the view. 395 * 396 * @see #setScrollIndicators(View, int) 397 * @see #setScrollIndicators(View, int, int) 398 * @see #getScrollIndicators(View) 399 */ 400 public static final int SCROLL_INDICATOR_END = 0x20; 401 402 static class ViewCompatBaseImpl { 403 private static Field sMinWidthField; 404 private static boolean sMinWidthFieldFetched; 405 private static Field sMinHeightField; 406 private static boolean sMinHeightFieldFetched; 407 private static WeakHashMap<View, String> sTransitionNameMap; 408 private Method mDispatchStartTemporaryDetach; 409 private Method mDispatchFinishTemporaryDetach; 410 private boolean mTempDetachBound; 411 WeakHashMap<View, ViewPropertyAnimatorCompat> mViewPropertyAnimatorCompatMap = null; 412 private static Method sChildrenDrawingOrderMethod; 413 static Field sAccessibilityDelegateField; 414 static boolean sAccessibilityDelegateCheckFailed = false; 415 416 public void setAccessibilityDelegate(View v, 417 @Nullable AccessibilityDelegateCompat delegate) { 418 v.setAccessibilityDelegate(delegate == null ? null : delegate.getBridge()); 419 } 420 421 public boolean hasAccessibilityDelegate(View v) { 422 if (sAccessibilityDelegateCheckFailed) { 423 return false; // View implementation might have changed. 424 } 425 if (sAccessibilityDelegateField == null) { 426 try { 427 sAccessibilityDelegateField = View.class 428 .getDeclaredField("mAccessibilityDelegate"); 429 sAccessibilityDelegateField.setAccessible(true); 430 } catch (Throwable t) { 431 sAccessibilityDelegateCheckFailed = true; 432 return false; 433 } 434 } 435 try { 436 return sAccessibilityDelegateField.get(v) != null; 437 } catch (Throwable t) { 438 sAccessibilityDelegateCheckFailed = true; 439 return false; 440 } 441 } 442 443 public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) { 444 v.onInitializeAccessibilityNodeInfo(info.unwrap()); 445 } 446 447 @SuppressWarnings("deprecation") 448 public boolean startDragAndDrop(View v, ClipData data, View.DragShadowBuilder shadowBuilder, 449 Object localState, int flags) { 450 return v.startDrag(data, shadowBuilder, localState, flags); 451 } 452 453 public void cancelDragAndDrop(View v) { 454 // no-op 455 } 456 457 public void updateDragShadow(View v, View.DragShadowBuilder shadowBuilder) { 458 // no-op 459 } 460 461 public boolean hasTransientState(View view) { 462 // A view can't have transient state if transient state wasn't supported. 463 return false; 464 } 465 466 public void setHasTransientState(View view, boolean hasTransientState) { 467 // Do nothing; API doesn't exist 468 } 469 470 public void postInvalidateOnAnimation(View view) { 471 view.invalidate(); 472 } 473 474 public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) { 475 view.invalidate(left, top, right, bottom); 476 } 477 478 public void postOnAnimation(View view, Runnable action) { 479 view.postDelayed(action, getFrameTime()); 480 } 481 482 public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) { 483 view.postDelayed(action, getFrameTime() + delayMillis); 484 } 485 486 long getFrameTime() { 487 return ValueAnimator.getFrameDelay(); 488 } 489 490 public int getImportantForAccessibility(View view) { 491 return 0; 492 } 493 494 public void setImportantForAccessibility(View view, int mode) { 495 } 496 497 public boolean isImportantForAccessibility(View view) { 498 return true; 499 } 500 501 public boolean performAccessibilityAction(View view, int action, Bundle arguments) { 502 return false; 503 } 504 505 public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) { 506 return null; 507 } 508 509 public int getLabelFor(View view) { 510 return 0; 511 } 512 513 public void setLabelFor(View view, int id) { 514 } 515 516 public void setLayerPaint(View view, Paint paint) { 517 // Make sure the paint is correct; this will be cheap if it's the same 518 // instance as was used to call setLayerType earlier. 519 view.setLayerType(view.getLayerType(), paint); 520 // This is expensive, but the only way to accomplish this before JB-MR1. 521 view.invalidate(); 522 } 523 524 public int getLayoutDirection(View view) { 525 return LAYOUT_DIRECTION_LTR; 526 } 527 528 public void setLayoutDirection(View view, int layoutDirection) { 529 // No-op 530 } 531 532 public ViewParent getParentForAccessibility(View view) { 533 return view.getParent(); 534 } 535 536 public int getAccessibilityLiveRegion(View view) { 537 return ACCESSIBILITY_LIVE_REGION_NONE; 538 } 539 540 public void setAccessibilityLiveRegion(View view, int mode) { 541 // No-op 542 } 543 544 public int getPaddingStart(View view) { 545 return view.getPaddingLeft(); 546 } 547 548 public int getPaddingEnd(View view) { 549 return view.getPaddingRight(); 550 } 551 552 public void setPaddingRelative(View view, int start, int top, int end, int bottom) { 553 view.setPadding(start, top, end, bottom); 554 } 555 556 public void dispatchStartTemporaryDetach(View view) { 557 if (!mTempDetachBound) { 558 bindTempDetach(); 559 } 560 if (mDispatchStartTemporaryDetach != null) { 561 try { 562 mDispatchStartTemporaryDetach.invoke(view); 563 } catch (Exception e) { 564 Log.d(TAG, "Error calling dispatchStartTemporaryDetach", e); 565 } 566 } else { 567 // Try this instead 568 view.onStartTemporaryDetach(); 569 } 570 } 571 572 public void dispatchFinishTemporaryDetach(View view) { 573 if (!mTempDetachBound) { 574 bindTempDetach(); 575 } 576 if (mDispatchFinishTemporaryDetach != null) { 577 try { 578 mDispatchFinishTemporaryDetach.invoke(view); 579 } catch (Exception e) { 580 Log.d(TAG, "Error calling dispatchFinishTemporaryDetach", e); 581 } 582 } else { 583 // Try this instead 584 view.onFinishTemporaryDetach(); 585 } 586 } 587 588 public boolean hasOverlappingRendering(View view) { 589 return true; 590 } 591 592 private void bindTempDetach() { 593 try { 594 mDispatchStartTemporaryDetach = View.class.getDeclaredMethod( 595 "dispatchStartTemporaryDetach"); 596 mDispatchFinishTemporaryDetach = View.class.getDeclaredMethod( 597 "dispatchFinishTemporaryDetach"); 598 } catch (NoSuchMethodException e) { 599 Log.e(TAG, "Couldn't find method", e); 600 } 601 mTempDetachBound = true; 602 } 603 604 public int getMinimumWidth(View view) { 605 if (!sMinWidthFieldFetched) { 606 try { 607 sMinWidthField = View.class.getDeclaredField("mMinWidth"); 608 sMinWidthField.setAccessible(true); 609 } catch (NoSuchFieldException e) { 610 // Couldn't find the field. Abort! 611 } 612 sMinWidthFieldFetched = true; 613 } 614 615 if (sMinWidthField != null) { 616 try { 617 return (int) sMinWidthField.get(view); 618 } catch (Exception e) { 619 // Field get failed. Oh well... 620 } 621 } 622 623 // We failed, return 0 624 return 0; 625 } 626 627 public int getMinimumHeight(View view) { 628 if (!sMinHeightFieldFetched) { 629 try { 630 sMinHeightField = View.class.getDeclaredField("mMinHeight"); 631 sMinHeightField.setAccessible(true); 632 } catch (NoSuchFieldException e) { 633 // Couldn't find the field. Abort! 634 } 635 sMinHeightFieldFetched = true; 636 } 637 638 if (sMinHeightField != null) { 639 try { 640 return (int) sMinHeightField.get(view); 641 } catch (Exception e) { 642 // Field get failed. Oh well... 643 } 644 } 645 646 // We failed, return 0 647 return 0; 648 } 649 650 public ViewPropertyAnimatorCompat animate(View view) { 651 if (mViewPropertyAnimatorCompatMap == null) { 652 mViewPropertyAnimatorCompatMap = new WeakHashMap<>(); 653 } 654 ViewPropertyAnimatorCompat vpa = mViewPropertyAnimatorCompatMap.get(view); 655 if (vpa == null) { 656 vpa = new ViewPropertyAnimatorCompat(view); 657 mViewPropertyAnimatorCompatMap.put(view, vpa); 658 } 659 return vpa; 660 } 661 662 public void setTransitionName(View view, String transitionName) { 663 if (sTransitionNameMap == null) { 664 sTransitionNameMap = new WeakHashMap<>(); 665 } 666 sTransitionNameMap.put(view, transitionName); 667 } 668 669 public String getTransitionName(View view) { 670 if (sTransitionNameMap == null) { 671 return null; 672 } 673 return sTransitionNameMap.get(view); 674 } 675 676 public int getWindowSystemUiVisibility(View view) { 677 return 0; 678 } 679 680 public void requestApplyInsets(View view) { 681 } 682 683 public void setElevation(View view, float elevation) { 684 } 685 686 public float getElevation(View view) { 687 return 0f; 688 } 689 690 public void setTranslationZ(View view, float translationZ) { 691 } 692 693 public float getTranslationZ(View view) { 694 return 0f; 695 } 696 697 public void setClipBounds(View view, Rect clipBounds) { 698 } 699 700 public Rect getClipBounds(View view) { 701 return null; 702 } 703 704 public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) { 705 if (sChildrenDrawingOrderMethod == null) { 706 try { 707 sChildrenDrawingOrderMethod = ViewGroup.class 708 .getDeclaredMethod("setChildrenDrawingOrderEnabled", boolean.class); 709 } catch (NoSuchMethodException e) { 710 Log.e(TAG, "Unable to find childrenDrawingOrderEnabled", e); 711 } 712 sChildrenDrawingOrderMethod.setAccessible(true); 713 } 714 try { 715 sChildrenDrawingOrderMethod.invoke(viewGroup, enabled); 716 } catch (IllegalAccessException e) { 717 Log.e(TAG, "Unable to invoke childrenDrawingOrderEnabled", e); 718 } catch (IllegalArgumentException e) { 719 Log.e(TAG, "Unable to invoke childrenDrawingOrderEnabled", e); 720 } catch (InvocationTargetException e) { 721 Log.e(TAG, "Unable to invoke childrenDrawingOrderEnabled", e); 722 } 723 } 724 725 public boolean getFitsSystemWindows(View view) { 726 return false; 727 } 728 729 public void setOnApplyWindowInsetsListener(View view, 730 OnApplyWindowInsetsListener listener) { 731 // noop 732 } 733 734 public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { 735 return insets; 736 } 737 738 public WindowInsetsCompat dispatchApplyWindowInsets(View v, WindowInsetsCompat insets) { 739 return insets; 740 } 741 742 public boolean isPaddingRelative(View view) { 743 return false; 744 } 745 746 public void setNestedScrollingEnabled(View view, boolean enabled) { 747 if (view instanceof NestedScrollingChild) { 748 ((NestedScrollingChild) view).setNestedScrollingEnabled(enabled); 749 } 750 } 751 752 public boolean isNestedScrollingEnabled(View view) { 753 if (view instanceof NestedScrollingChild) { 754 return ((NestedScrollingChild) view).isNestedScrollingEnabled(); 755 } 756 return false; 757 } 758 759 public void setBackground(View view, Drawable background) { 760 view.setBackgroundDrawable(background); 761 } 762 763 public ColorStateList getBackgroundTintList(View view) { 764 return (view instanceof TintableBackgroundView) 765 ? ((TintableBackgroundView) view).getSupportBackgroundTintList() 766 : null; 767 } 768 769 public void setBackgroundTintList(View view, ColorStateList tintList) { 770 if (view instanceof TintableBackgroundView) { 771 ((TintableBackgroundView) view).setSupportBackgroundTintList(tintList); 772 } 773 } 774 775 public void setBackgroundTintMode(View view, PorterDuff.Mode mode) { 776 if (view instanceof TintableBackgroundView) { 777 ((TintableBackgroundView) view).setSupportBackgroundTintMode(mode); 778 } 779 } 780 781 public PorterDuff.Mode getBackgroundTintMode(View view) { 782 return (view instanceof TintableBackgroundView) 783 ? ((TintableBackgroundView) view).getSupportBackgroundTintMode() 784 : null; 785 } 786 787 public boolean startNestedScroll(View view, int axes) { 788 if (view instanceof NestedScrollingChild) { 789 return ((NestedScrollingChild) view).startNestedScroll(axes); 790 } 791 return false; 792 } 793 794 public void stopNestedScroll(View view) { 795 if (view instanceof NestedScrollingChild) { 796 ((NestedScrollingChild) view).stopNestedScroll(); 797 } 798 } 799 800 public boolean hasNestedScrollingParent(View view) { 801 if (view instanceof NestedScrollingChild) { 802 return ((NestedScrollingChild) view).hasNestedScrollingParent(); 803 } 804 return false; 805 } 806 807 public boolean dispatchNestedScroll(View view, int dxConsumed, int dyConsumed, 808 int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { 809 if (view instanceof NestedScrollingChild) { 810 return ((NestedScrollingChild) view).dispatchNestedScroll(dxConsumed, dyConsumed, 811 dxUnconsumed, dyUnconsumed, offsetInWindow); 812 } 813 return false; 814 } 815 816 public boolean dispatchNestedPreScroll(View view, int dx, int dy, 817 int[] consumed, int[] offsetInWindow) { 818 if (view instanceof NestedScrollingChild) { 819 return ((NestedScrollingChild) view).dispatchNestedPreScroll(dx, dy, consumed, 820 offsetInWindow); 821 } 822 return false; 823 } 824 825 public boolean dispatchNestedFling(View view, float velocityX, float velocityY, 826 boolean consumed) { 827 if (view instanceof NestedScrollingChild) { 828 return ((NestedScrollingChild) view).dispatchNestedFling(velocityX, velocityY, 829 consumed); 830 } 831 return false; 832 } 833 834 public boolean dispatchNestedPreFling(View view, float velocityX, float velocityY) { 835 if (view instanceof NestedScrollingChild) { 836 return ((NestedScrollingChild) view).dispatchNestedPreFling(velocityX, velocityY); 837 } 838 return false; 839 } 840 841 public boolean isInLayout(View view) { 842 return false; 843 } 844 845 public boolean isLaidOut(View view) { 846 return view.getWidth() > 0 && view.getHeight() > 0; 847 } 848 849 public boolean isLayoutDirectionResolved(View view) { 850 return false; 851 } 852 853 public float getZ(View view) { 854 return getTranslationZ(view) + getElevation(view); 855 } 856 857 public void setZ(View view, float z) { 858 // no-op 859 } 860 861 public boolean isAttachedToWindow(View view) { 862 return view.getWindowToken() != null; 863 } 864 865 public boolean hasOnClickListeners(View view) { 866 return false; 867 } 868 869 public int getScrollIndicators(View view) { 870 return 0; 871 } 872 873 public void setScrollIndicators(View view, int indicators) { 874 // no-op 875 } 876 877 public void setScrollIndicators(View view, int indicators, int mask) { 878 // no-op 879 } 880 881 public void offsetLeftAndRight(View view, int offset) { 882 view.offsetLeftAndRight(offset); 883 if (view.getVisibility() == View.VISIBLE) { 884 tickleInvalidationFlag(view); 885 886 ViewParent parent = view.getParent(); 887 if (parent instanceof View) { 888 tickleInvalidationFlag((View) parent); 889 } 890 } 891 } 892 893 public void offsetTopAndBottom(View view, int offset) { 894 view.offsetTopAndBottom(offset); 895 if (view.getVisibility() == View.VISIBLE) { 896 tickleInvalidationFlag(view); 897 898 ViewParent parent = view.getParent(); 899 if (parent instanceof View) { 900 tickleInvalidationFlag((View) parent); 901 } 902 } 903 } 904 905 private static void tickleInvalidationFlag(View view) { 906 final float y = view.getTranslationY(); 907 view.setTranslationY(y + 1); 908 view.setTranslationY(y); 909 } 910 911 public void setPointerIcon(View view, PointerIconCompat pointerIcon) { 912 // no-op 913 } 914 915 public Display getDisplay(View view) { 916 if (isAttachedToWindow(view)) { 917 final WindowManager wm = (WindowManager) view.getContext().getSystemService( 918 Context.WINDOW_SERVICE); 919 return wm.getDefaultDisplay(); 920 } 921 return null; 922 } 923 924 public void setTooltipText(View view, CharSequence tooltipText) { 925 } 926 } 927 928 @RequiresApi(15) 929 static class ViewCompatApi15Impl extends ViewCompatBaseImpl { 930 @Override 931 public boolean hasOnClickListeners(View view) { 932 return view.hasOnClickListeners(); 933 } 934 } 935 936 @RequiresApi(16) 937 static class ViewCompatApi16Impl extends ViewCompatApi15Impl { 938 @Override 939 public boolean hasTransientState(View view) { 940 return view.hasTransientState(); 941 } 942 @Override 943 public void setHasTransientState(View view, boolean hasTransientState) { 944 view.setHasTransientState(hasTransientState); 945 } 946 @Override 947 public void postInvalidateOnAnimation(View view) { 948 view.postInvalidateOnAnimation(); 949 } 950 @Override 951 public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) { 952 view.postInvalidateOnAnimation(left, top, right, bottom); 953 } 954 @Override 955 public void postOnAnimation(View view, Runnable action) { 956 view.postOnAnimation(action); 957 } 958 @Override 959 public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) { 960 view.postOnAnimationDelayed(action, delayMillis); 961 } 962 @Override 963 public int getImportantForAccessibility(View view) { 964 return view.getImportantForAccessibility(); 965 } 966 @Override 967 public void setImportantForAccessibility(View view, int mode) { 968 // IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS is not available 969 // on this platform so replace with IMPORTANT_FOR_ACCESSIBILITY_NO 970 // which is closer semantically. 971 if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) { 972 mode = IMPORTANT_FOR_ACCESSIBILITY_NO; 973 } 974 //noinspection WrongConstant 975 view.setImportantForAccessibility(mode); 976 } 977 @Override 978 public boolean performAccessibilityAction(View view, int action, Bundle arguments) { 979 return view.performAccessibilityAction(action, arguments); 980 } 981 @Override 982 public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) { 983 AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider(); 984 if (provider != null) { 985 return new AccessibilityNodeProviderCompat(provider); 986 } 987 return null; 988 } 989 990 @Override 991 public ViewParent getParentForAccessibility(View view) { 992 return view.getParentForAccessibility(); 993 } 994 995 @Override 996 public int getMinimumWidth(View view) { 997 return view.getMinimumWidth(); 998 } 999 1000 @Override 1001 public int getMinimumHeight(View view) { 1002 return view.getMinimumHeight(); 1003 } 1004 1005 @SuppressWarnings("deprecation") 1006 @Override 1007 public void requestApplyInsets(View view) { 1008 view.requestFitSystemWindows(); 1009 } 1010 1011 @Override 1012 public boolean getFitsSystemWindows(View view) { 1013 return view.getFitsSystemWindows(); 1014 } 1015 1016 @Override 1017 public boolean hasOverlappingRendering(View view) { 1018 return view.hasOverlappingRendering(); 1019 } 1020 1021 @Override 1022 public void setBackground(View view, Drawable background) { 1023 view.setBackground(background); 1024 } 1025 } 1026 1027 @RequiresApi(17) 1028 static class ViewCompatApi17Impl extends ViewCompatApi16Impl { 1029 1030 @Override 1031 public int getLabelFor(View view) { 1032 return view.getLabelFor(); 1033 } 1034 1035 @Override 1036 public void setLabelFor(View view, int id) { 1037 view.setLabelFor(id); 1038 } 1039 1040 @Override 1041 public void setLayerPaint(View view, Paint paint) { 1042 view.setLayerPaint(paint); 1043 } 1044 1045 @Override 1046 public int getLayoutDirection(View view) { 1047 return view.getLayoutDirection(); 1048 } 1049 1050 @Override 1051 public void setLayoutDirection(View view, int layoutDirection) { 1052 view.setLayoutDirection(layoutDirection); 1053 } 1054 1055 @Override 1056 public int getPaddingStart(View view) { 1057 return view.getPaddingStart(); 1058 } 1059 1060 @Override 1061 public int getPaddingEnd(View view) { 1062 return view.getPaddingEnd(); 1063 } 1064 1065 @Override 1066 public void setPaddingRelative(View view, int start, int top, int end, int bottom) { 1067 view.setPaddingRelative(start, top, end, bottom); 1068 } 1069 1070 @Override 1071 public int getWindowSystemUiVisibility(View view) { 1072 return view.getWindowSystemUiVisibility(); 1073 } 1074 1075 @Override 1076 public boolean isPaddingRelative(View view) { 1077 return view.isPaddingRelative(); 1078 } 1079 1080 @Override 1081 public Display getDisplay(View view) { 1082 return view.getDisplay(); 1083 } 1084 } 1085 1086 @RequiresApi(18) 1087 static class ViewCompatApi18Impl extends ViewCompatApi17Impl { 1088 @Override 1089 public void setClipBounds(View view, Rect clipBounds) { 1090 view.setClipBounds(clipBounds); 1091 } 1092 1093 @Override 1094 public Rect getClipBounds(View view) { 1095 return view.getClipBounds(); 1096 } 1097 1098 @Override 1099 public boolean isInLayout(View view) { 1100 return view.isInLayout(); 1101 } 1102 } 1103 1104 @RequiresApi(19) 1105 static class ViewCompatApi19Impl extends ViewCompatApi18Impl { 1106 @Override 1107 public int getAccessibilityLiveRegion(View view) { 1108 return view.getAccessibilityLiveRegion(); 1109 } 1110 1111 @Override 1112 public void setAccessibilityLiveRegion(View view, int mode) { 1113 view.setAccessibilityLiveRegion(mode); 1114 } 1115 1116 @Override 1117 public void setImportantForAccessibility(View view, int mode) { 1118 view.setImportantForAccessibility(mode); 1119 } 1120 1121 @Override 1122 public boolean isLaidOut(View view) { 1123 return view.isLaidOut(); 1124 } 1125 1126 @Override 1127 public boolean isLayoutDirectionResolved(View view) { 1128 return view.isLayoutDirectionResolved(); 1129 } 1130 1131 @Override 1132 public boolean isAttachedToWindow(View view) { 1133 return view.isAttachedToWindow(); 1134 } 1135 } 1136 1137 @RequiresApi(21) 1138 static class ViewCompatApi21Impl extends ViewCompatApi19Impl { 1139 private static ThreadLocal<Rect> sThreadLocalRect; 1140 1141 @Override 1142 public void setTransitionName(View view, String transitionName) { 1143 view.setTransitionName(transitionName); 1144 } 1145 1146 @Override 1147 public String getTransitionName(View view) { 1148 return view.getTransitionName(); 1149 } 1150 1151 @Override 1152 public void requestApplyInsets(View view) { 1153 view.requestApplyInsets(); 1154 } 1155 1156 @Override 1157 public void setElevation(View view, float elevation) { 1158 view.setElevation(elevation); 1159 } 1160 1161 @Override 1162 public float getElevation(View view) { 1163 return view.getElevation(); 1164 } 1165 1166 @Override 1167 public void setTranslationZ(View view, float translationZ) { 1168 view.setTranslationZ(translationZ); 1169 } 1170 1171 @Override 1172 public float getTranslationZ(View view) { 1173 return view.getTranslationZ(); 1174 } 1175 1176 @Override 1177 public void setOnApplyWindowInsetsListener(View view, 1178 final OnApplyWindowInsetsListener listener) { 1179 if (listener == null) { 1180 view.setOnApplyWindowInsetsListener(null); 1181 return; 1182 } 1183 1184 view.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { 1185 @Override 1186 public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { 1187 WindowInsetsCompat compatInsets = WindowInsetsCompat.wrap(insets); 1188 compatInsets = listener.onApplyWindowInsets(view, compatInsets); 1189 return (WindowInsets) WindowInsetsCompat.unwrap(compatInsets); 1190 } 1191 }); 1192 } 1193 1194 @Override 1195 public void setNestedScrollingEnabled(View view, boolean enabled) { 1196 view.setNestedScrollingEnabled(enabled); 1197 } 1198 1199 @Override 1200 public boolean isNestedScrollingEnabled(View view) { 1201 return view.isNestedScrollingEnabled(); 1202 } 1203 1204 @Override 1205 public boolean startNestedScroll(View view, int axes) { 1206 return view.startNestedScroll(axes); 1207 } 1208 1209 @Override 1210 public void stopNestedScroll(View view) { 1211 view.stopNestedScroll(); 1212 } 1213 1214 @Override 1215 public boolean hasNestedScrollingParent(View view) { 1216 return view.hasNestedScrollingParent(); 1217 } 1218 1219 @Override 1220 public boolean dispatchNestedScroll(View view, int dxConsumed, int dyConsumed, 1221 int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { 1222 return view.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, 1223 offsetInWindow); 1224 } 1225 1226 @Override 1227 public boolean dispatchNestedPreScroll(View view, int dx, int dy, 1228 int[] consumed, int[] offsetInWindow) { 1229 return view.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow); 1230 } 1231 1232 @Override 1233 public boolean dispatchNestedFling(View view, float velocityX, float velocityY, 1234 boolean consumed) { 1235 return view.dispatchNestedFling(velocityX, velocityY, consumed); 1236 } 1237 1238 @Override 1239 public boolean dispatchNestedPreFling(View view, float velocityX, float velocityY) { 1240 return view.dispatchNestedPreFling(velocityX, velocityY); 1241 } 1242 1243 @Override 1244 public boolean isImportantForAccessibility(View view) { 1245 return view.isImportantForAccessibility(); 1246 } 1247 1248 @Override 1249 public ColorStateList getBackgroundTintList(View view) { 1250 return view.getBackgroundTintList(); 1251 } 1252 1253 @Override 1254 public void setBackgroundTintList(View view, ColorStateList tintList) { 1255 view.setBackgroundTintList(tintList); 1256 1257 if (Build.VERSION.SDK_INT == 21) { 1258 // Work around a bug in L that did not update the state of the background 1259 // after applying the tint 1260 Drawable background = view.getBackground(); 1261 boolean hasTint = (view.getBackgroundTintList() != null) 1262 && (view.getBackgroundTintMode() != null); 1263 if ((background != null) && hasTint) { 1264 if (background.isStateful()) { 1265 background.setState(view.getDrawableState()); 1266 } 1267 view.setBackground(background); 1268 } 1269 } 1270 } 1271 1272 @Override 1273 public void setBackgroundTintMode(View view, PorterDuff.Mode mode) { 1274 view.setBackgroundTintMode(mode); 1275 1276 if (Build.VERSION.SDK_INT == 21) { 1277 // Work around a bug in L that did not update the state of the background 1278 // after applying the tint 1279 Drawable background = view.getBackground(); 1280 boolean hasTint = (view.getBackgroundTintList() != null) 1281 && (view.getBackgroundTintMode() != null); 1282 if ((background != null) && hasTint) { 1283 if (background.isStateful()) { 1284 background.setState(view.getDrawableState()); 1285 } 1286 view.setBackground(background); 1287 } 1288 } 1289 } 1290 1291 @Override 1292 public PorterDuff.Mode getBackgroundTintMode(View view) { 1293 return view.getBackgroundTintMode(); 1294 } 1295 1296 @Override 1297 public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { 1298 WindowInsets unwrapped = (WindowInsets) WindowInsetsCompat.unwrap(insets); 1299 WindowInsets result = v.onApplyWindowInsets(unwrapped); 1300 if (result != unwrapped) { 1301 unwrapped = new WindowInsets(result); 1302 } 1303 return WindowInsetsCompat.wrap(unwrapped); 1304 } 1305 1306 @Override 1307 public WindowInsetsCompat dispatchApplyWindowInsets(View v, WindowInsetsCompat insets) { 1308 WindowInsets unwrapped = (WindowInsets) WindowInsetsCompat.unwrap(insets); 1309 WindowInsets result = v.dispatchApplyWindowInsets(unwrapped); 1310 if (result != unwrapped) { 1311 unwrapped = new WindowInsets(result); 1312 } 1313 return WindowInsetsCompat.wrap(unwrapped); 1314 } 1315 1316 @Override 1317 public float getZ(View view) { 1318 return view.getZ(); 1319 } 1320 1321 @Override 1322 public void setZ(View view, float z) { 1323 view.setZ(z); 1324 } 1325 1326 @Override 1327 public void offsetLeftAndRight(View view, int offset) { 1328 final Rect parentRect = getEmptyTempRect(); 1329 boolean needInvalidateWorkaround = false; 1330 1331 final ViewParent parent = view.getParent(); 1332 if (parent instanceof View) { 1333 final View p = (View) parent; 1334 parentRect.set(p.getLeft(), p.getTop(), p.getRight(), p.getBottom()); 1335 // If the view currently does not currently intersect the parent (and is therefore 1336 // not displayed) we may need need to invalidate 1337 needInvalidateWorkaround = !parentRect.intersects(view.getLeft(), view.getTop(), 1338 view.getRight(), view.getBottom()); 1339 } 1340 1341 // Now offset, invoking the API 11+ implementation (which contains its own workarounds) 1342 super.offsetLeftAndRight(view, offset); 1343 1344 // The view has now been offset, so let's intersect the Rect and invalidate where 1345 // the View is now displayed 1346 if (needInvalidateWorkaround && parentRect.intersect(view.getLeft(), view.getTop(), 1347 view.getRight(), view.getBottom())) { 1348 ((View) parent).invalidate(parentRect); 1349 } 1350 } 1351 1352 @Override 1353 public void offsetTopAndBottom(View view, int offset) { 1354 final Rect parentRect = getEmptyTempRect(); 1355 boolean needInvalidateWorkaround = false; 1356 1357 final ViewParent parent = view.getParent(); 1358 if (parent instanceof View) { 1359 final View p = (View) parent; 1360 parentRect.set(p.getLeft(), p.getTop(), p.getRight(), p.getBottom()); 1361 // If the view currently does not currently intersect the parent (and is therefore 1362 // not displayed) we may need need to invalidate 1363 needInvalidateWorkaround = !parentRect.intersects(view.getLeft(), view.getTop(), 1364 view.getRight(), view.getBottom()); 1365 } 1366 1367 // Now offset, invoking the API 11+ implementation (which contains its own workarounds) 1368 super.offsetTopAndBottom(view, offset); 1369 1370 // The view has now been offset, so let's intersect the Rect and invalidate where 1371 // the View is now displayed 1372 if (needInvalidateWorkaround && parentRect.intersect(view.getLeft(), view.getTop(), 1373 view.getRight(), view.getBottom())) { 1374 ((View) parent).invalidate(parentRect); 1375 } 1376 } 1377 1378 private static Rect getEmptyTempRect() { 1379 if (sThreadLocalRect == null) { 1380 sThreadLocalRect = new ThreadLocal<>(); 1381 } 1382 Rect rect = sThreadLocalRect.get(); 1383 if (rect == null) { 1384 rect = new Rect(); 1385 sThreadLocalRect.set(rect); 1386 } 1387 rect.setEmpty(); 1388 return rect; 1389 } 1390 } 1391 1392 @RequiresApi(23) 1393 static class ViewCompatApi23Impl extends ViewCompatApi21Impl { 1394 @Override 1395 public void setScrollIndicators(View view, int indicators) { 1396 view.setScrollIndicators(indicators); 1397 } 1398 1399 @Override 1400 public void setScrollIndicators(View view, int indicators, int mask) { 1401 view.setScrollIndicators(indicators, mask); 1402 } 1403 1404 @Override 1405 public int getScrollIndicators(View view) { 1406 return view.getScrollIndicators(); 1407 } 1408 1409 1410 @Override 1411 public void offsetLeftAndRight(View view, int offset) { 1412 view.offsetLeftAndRight(offset); 1413 } 1414 1415 @Override 1416 public void offsetTopAndBottom(View view, int offset) { 1417 view.offsetTopAndBottom(offset); 1418 } 1419 } 1420 1421 @RequiresApi(24) 1422 static class ViewCompatApi24Impl extends ViewCompatApi23Impl { 1423 @Override 1424 public void dispatchStartTemporaryDetach(View view) { 1425 view.dispatchStartTemporaryDetach(); 1426 } 1427 1428 @Override 1429 public void dispatchFinishTemporaryDetach(View view) { 1430 view.dispatchFinishTemporaryDetach(); 1431 } 1432 1433 @Override 1434 public void setPointerIcon(View view, PointerIconCompat pointerIconCompat) { 1435 view.setPointerIcon((PointerIcon) (pointerIconCompat != null 1436 ? pointerIconCompat.getPointerIcon() : null)); 1437 } 1438 1439 @Override 1440 public boolean startDragAndDrop(View view, ClipData data, 1441 View.DragShadowBuilder shadowBuilder, Object localState, int flags) { 1442 return view.startDragAndDrop(data, shadowBuilder, localState, flags); 1443 } 1444 1445 @Override 1446 public void cancelDragAndDrop(View view) { 1447 view.cancelDragAndDrop(); 1448 } 1449 1450 @Override 1451 public void updateDragShadow(View view, View.DragShadowBuilder shadowBuilder) { 1452 view.updateDragShadow(shadowBuilder); 1453 } 1454 } 1455 1456 @RequiresApi(26) 1457 static class ViewCompatApi26Impl extends ViewCompatApi24Impl { 1458 @Override 1459 public void setTooltipText(View view, CharSequence tooltipText) { 1460 view.setTooltipText(tooltipText); 1461 } 1462 } 1463 1464 static final ViewCompatBaseImpl IMPL; 1465 static { 1466 if (BuildCompat.isAtLeastO()) { 1467 //noinspection AndroidLintNewApi 1468 IMPL = new ViewCompatApi26Impl(); 1469 } else if (Build.VERSION.SDK_INT >= 24) { 1470 IMPL = new ViewCompatApi24Impl(); 1471 } else if (Build.VERSION.SDK_INT >= 23) { 1472 IMPL = new ViewCompatApi23Impl(); 1473 } else if (Build.VERSION.SDK_INT >= 21) { 1474 IMPL = new ViewCompatApi21Impl(); 1475 } else if (Build.VERSION.SDK_INT >= 19) { 1476 IMPL = new ViewCompatApi19Impl(); 1477 } else if (Build.VERSION.SDK_INT >= 18) { 1478 IMPL = new ViewCompatApi18Impl(); 1479 } else if (Build.VERSION.SDK_INT >= 17) { 1480 IMPL = new ViewCompatApi17Impl(); 1481 } else if (Build.VERSION.SDK_INT >= 16) { 1482 IMPL = new ViewCompatApi16Impl(); 1483 } else if (Build.VERSION.SDK_INT >= 15) { 1484 IMPL = new ViewCompatApi15Impl(); 1485 } else { 1486 IMPL = new ViewCompatBaseImpl(); 1487 } 1488 } 1489 1490 /** 1491 * Check if this view can be scrolled horizontally in a certain direction. 1492 * 1493 * @param view The View against which to invoke the method. 1494 * @param direction Negative to check scrolling left, positive to check scrolling right. 1495 * @return true if this view can be scrolled in the specified direction, false otherwise. 1496 * 1497 * @deprecated Use {@link View#canScrollHorizontally(int)} directly. 1498 */ 1499 @Deprecated 1500 public static boolean canScrollHorizontally(View view, int direction) { 1501 return view.canScrollHorizontally(direction); 1502 } 1503 1504 /** 1505 * Check if this view can be scrolled vertically in a certain direction. 1506 * 1507 * @param view The View against which to invoke the method. 1508 * @param direction Negative to check scrolling up, positive to check scrolling down. 1509 * @return true if this view can be scrolled in the specified direction, false otherwise. 1510 * 1511 * @deprecated Use {@link View#canScrollVertically(int)} directly. 1512 */ 1513 @Deprecated 1514 public static boolean canScrollVertically(View view, int direction) { 1515 return view.canScrollVertically(direction); 1516 } 1517 1518 /** 1519 * Returns the over-scroll mode for this view. The result will be 1520 * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS} 1521 * (allow over-scrolling only if the view content is larger than the container), 1522 * or {@link #OVER_SCROLL_NEVER}. 1523 * 1524 * @param v The View against which to invoke the method. 1525 * @return This view's over-scroll mode. 1526 * @deprecated Call {@link View#getOverScrollMode()} directly. This method will be 1527 * removed in a future release. 1528 */ 1529 @Deprecated 1530 @OverScroll 1531 public static int getOverScrollMode(View v) { 1532 //noinspection ResourceType 1533 return v.getOverScrollMode(); 1534 } 1535 1536 /** 1537 * Set the over-scroll mode for this view. Valid over-scroll modes are 1538 * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS} 1539 * (allow over-scrolling only if the view content is larger than the container), 1540 * or {@link #OVER_SCROLL_NEVER}. 1541 * 1542 * Setting the over-scroll mode of a view will have an effect only if the 1543 * view is capable of scrolling. 1544 * 1545 * @param v The View against which to invoke the method. 1546 * @param overScrollMode The new over-scroll mode for this view. 1547 * @deprecated Call {@link View#setOverScrollMode(int)} directly. This method will be 1548 * removed in a future release. 1549 */ 1550 @Deprecated 1551 public static void setOverScrollMode(View v, @OverScroll int overScrollMode) { 1552 v.setOverScrollMode(overScrollMode); 1553 } 1554 1555 /** 1556 * Called from {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} 1557 * giving a chance to this View to populate the accessibility event with its 1558 * text content. While this method is free to modify event 1559 * attributes other than text content, doing so should normally be performed in 1560 * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)}. 1561 * <p> 1562 * Example: Adding formatted date string to an accessibility event in addition 1563 * to the text added by the super implementation: 1564 * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 1565 * super.onPopulateAccessibilityEvent(event); 1566 * final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY; 1567 * String selectedDateUtterance = DateUtils.formatDateTime(mContext, 1568 * mCurrentDate.getTimeInMillis(), flags); 1569 * event.getText().add(selectedDateUtterance); 1570 * }</pre> 1571 * <p> 1572 * If an {@link AccessibilityDelegateCompat} has been specified via calling 1573 * {@link ViewCompat#setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its 1574 * {@link AccessibilityDelegateCompat#onPopulateAccessibilityEvent(View, AccessibilityEvent)} 1575 * is responsible for handling this call. 1576 * </p> 1577 * <p class="note"><strong>Note:</strong> Always call the super implementation before adding 1578 * information to the event, in case the default implementation has basic information to add. 1579 * </p> 1580 * 1581 * @param v The View against which to invoke the method. 1582 * @param event The accessibility event which to populate. 1583 * 1584 * @see View#sendAccessibilityEvent(int) 1585 * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) 1586 * 1587 * @deprecated Call {@link View#onPopulateAccessibilityEvent(AccessibilityEvent)} directly. 1588 * This method will be removed in a future release. 1589 */ 1590 @Deprecated 1591 public static void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) { 1592 v.onPopulateAccessibilityEvent(event); 1593 } 1594 1595 /** 1596 * Initializes an {@link AccessibilityEvent} with information about 1597 * this View which is the event source. In other words, the source of 1598 * an accessibility event is the view whose state change triggered firing 1599 * the event. 1600 * <p> 1601 * Example: Setting the password property of an event in addition 1602 * to properties set by the super implementation: 1603 * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 1604 * super.onInitializeAccessibilityEvent(event); 1605 * event.setPassword(true); 1606 * }</pre> 1607 * <p> 1608 * If an {@link AccessibilityDelegateCompat} has been specified via calling 1609 * {@link ViewCompat#setAccessibilityDelegate(View, AccessibilityDelegateCompat)}, its 1610 * {@link AccessibilityDelegateCompat#onInitializeAccessibilityEvent(View, AccessibilityEvent)} 1611 * is responsible for handling this call. 1612 * 1613 * @param v The View against which to invoke the method. 1614 * @param event The event to initialize. 1615 * 1616 * @see View#sendAccessibilityEvent(int) 1617 * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) 1618 * 1619 * @deprecated Call {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)} directly. 1620 * This method will be removed in a future release. 1621 */ 1622 @Deprecated 1623 public static void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) { 1624 v.onInitializeAccessibilityEvent(event); 1625 } 1626 1627 /** 1628 * Initializes an {@link AccessibilityNodeInfoCompat} with information 1629 * about this view. The base implementation sets: 1630 * <ul> 1631 * <li>{@link AccessibilityNodeInfoCompat#setParent(View)},</li> 1632 * <li>{@link AccessibilityNodeInfoCompat#setBoundsInParent(Rect)},</li> 1633 * <li>{@link AccessibilityNodeInfoCompat#setBoundsInScreen(Rect)},</li> 1634 * <li>{@link AccessibilityNodeInfoCompat#setPackageName(CharSequence)},</li> 1635 * <li>{@link AccessibilityNodeInfoCompat#setClassName(CharSequence)},</li> 1636 * <li>{@link AccessibilityNodeInfoCompat#setContentDescription(CharSequence)},</li> 1637 * <li>{@link AccessibilityNodeInfoCompat#setEnabled(boolean)},</li> 1638 * <li>{@link AccessibilityNodeInfoCompat#setClickable(boolean)},</li> 1639 * <li>{@link AccessibilityNodeInfoCompat#setFocusable(boolean)},</li> 1640 * <li>{@link AccessibilityNodeInfoCompat#setFocused(boolean)},</li> 1641 * <li>{@link AccessibilityNodeInfoCompat#setLongClickable(boolean)},</li> 1642 * <li>{@link AccessibilityNodeInfoCompat#setSelected(boolean)},</li> 1643 * </ul> 1644 * <p> 1645 * If an {@link AccessibilityDelegateCompat} has been specified via calling 1646 * {@link ViewCompat#setAccessibilityDelegate(View, AccessibilityDelegateCompat)}, its 1647 * {@link AccessibilityDelegateCompat#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)} 1648 * method is responsible for handling this call. 1649 * 1650 * @param v The View against which to invoke the method. 1651 * @param info The instance to initialize. 1652 */ 1653 public static void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) { 1654 IMPL.onInitializeAccessibilityNodeInfo(v, info); 1655 } 1656 1657 /** 1658 * Sets a delegate for implementing accessibility support via composition 1659 * (as opposed to inheritance). For more details, see 1660 * {@link AccessibilityDelegateCompat}. 1661 * <p> 1662 * <strong>Note:</strong> On platform versions prior to 1663 * {@link android.os.Build.VERSION_CODES#M API 23}, delegate methods on 1664 * views in the {@code android.widget.*} package are called <i>before</i> 1665 * host methods. This prevents certain properties such as class name from 1666 * being modified by overriding 1667 * {@link AccessibilityDelegateCompat#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)}, 1668 * as any changes will be overwritten by the host class. 1669 * <p> 1670 * Starting in {@link android.os.Build.VERSION_CODES#M API 23}, delegate 1671 * methods are called <i>after</i> host methods, which all properties to be 1672 * modified without being overwritten by the host class. 1673 * 1674 * @param delegate the object to which accessibility method calls should be 1675 * delegated 1676 * @see AccessibilityDelegateCompat 1677 */ 1678 public static void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) { 1679 IMPL.setAccessibilityDelegate(v, delegate); 1680 } 1681 1682 /** 1683 * Checks whether provided View has an accessibility delegate attached to it. 1684 * 1685 * @param v The View instance to check 1686 * @return True if the View has an accessibility delegate 1687 */ 1688 public static boolean hasAccessibilityDelegate(View v) { 1689 return IMPL.hasAccessibilityDelegate(v); 1690 } 1691 1692 /** 1693 * Indicates whether the view is currently tracking transient state that the 1694 * app should not need to concern itself with saving and restoring, but that 1695 * the framework should take special note to preserve when possible. 1696 * 1697 * @param view View to check for transient state 1698 * @return true if the view has transient state 1699 */ 1700 public static boolean hasTransientState(View view) { 1701 return IMPL.hasTransientState(view); 1702 } 1703 1704 /** 1705 * Set whether this view is currently tracking transient state that the 1706 * framework should attempt to preserve when possible. 1707 * 1708 * @param view View tracking transient state 1709 * @param hasTransientState true if this view has transient state 1710 */ 1711 public static void setHasTransientState(View view, boolean hasTransientState) { 1712 IMPL.setHasTransientState(view, hasTransientState); 1713 } 1714 1715 /** 1716 * <p>Cause an invalidate to happen on the next animation time step, typically the 1717 * next display frame.</p> 1718 * 1719 * <p>This method can be invoked from outside of the UI thread 1720 * only when this View is attached to a window.</p> 1721 * 1722 * @param view View to invalidate 1723 */ 1724 public static void postInvalidateOnAnimation(View view) { 1725 IMPL.postInvalidateOnAnimation(view); 1726 } 1727 1728 /** 1729 * <p>Cause an invalidate of the specified area to happen on the next animation 1730 * time step, typically the next display frame.</p> 1731 * 1732 * <p>This method can be invoked from outside of the UI thread 1733 * only when this View is attached to a window.</p> 1734 * 1735 * @param view View to invalidate 1736 * @param left The left coordinate of the rectangle to invalidate. 1737 * @param top The top coordinate of the rectangle to invalidate. 1738 * @param right The right coordinate of the rectangle to invalidate. 1739 * @param bottom The bottom coordinate of the rectangle to invalidate. 1740 */ 1741 public static void postInvalidateOnAnimation(View view, int left, int top, 1742 int right, int bottom) { 1743 IMPL.postInvalidateOnAnimation(view, left, top, right, bottom); 1744 } 1745 1746 /** 1747 * <p>Causes the Runnable to execute on the next animation time step. 1748 * The runnable will be run on the user interface thread.</p> 1749 * 1750 * <p>This method can be invoked from outside of the UI thread 1751 * only when this View is attached to a window.</p> 1752 * 1753 * @param view View to post this Runnable to 1754 * @param action The Runnable that will be executed. 1755 */ 1756 public static void postOnAnimation(View view, Runnable action) { 1757 IMPL.postOnAnimation(view, action); 1758 } 1759 1760 /** 1761 * <p>Causes the Runnable to execute on the next animation time step, 1762 * after the specified amount of time elapses. 1763 * The runnable will be run on the user interface thread.</p> 1764 * 1765 * <p>This method can be invoked from outside of the UI thread 1766 * only when this View is attached to a window.</p> 1767 * 1768 * @param view The view to post this Runnable to 1769 * @param action The Runnable that will be executed. 1770 * @param delayMillis The delay (in milliseconds) until the Runnable 1771 * will be executed. 1772 */ 1773 public static void postOnAnimationDelayed(View view, Runnable action, long delayMillis) { 1774 IMPL.postOnAnimationDelayed(view, action, delayMillis); 1775 } 1776 1777 /** 1778 * Gets the mode for determining whether this View is important for accessibility 1779 * which is if it fires accessibility events and if it is reported to 1780 * accessibility services that query the screen. 1781 * 1782 * @param view The view whose property to get. 1783 * @return The mode for determining whether a View is important for accessibility. 1784 * 1785 * @see #IMPORTANT_FOR_ACCESSIBILITY_YES 1786 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO 1787 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS 1788 * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO 1789 */ 1790 @ImportantForAccessibility 1791 public static int getImportantForAccessibility(View view) { 1792 //noinspection ResourceType 1793 return IMPL.getImportantForAccessibility(view); 1794 } 1795 1796 /** 1797 * Sets how to determine whether this view is important for accessibility 1798 * which is if it fires accessibility events and if it is reported to 1799 * accessibility services that query the screen. 1800 * <p> 1801 * <em>Note:</em> If the current platform version does not support the 1802 * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} mode, then 1803 * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO} will be used as it is the 1804 * closest terms of semantics. 1805 * </p> 1806 * 1807 * @param view The view whose property to set. 1808 * @param mode How to determine whether this view is important for accessibility. 1809 * 1810 * @see #IMPORTANT_FOR_ACCESSIBILITY_YES 1811 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO 1812 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS 1813 * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO 1814 */ 1815 public static void setImportantForAccessibility(View view, 1816 @ImportantForAccessibility int mode) { 1817 IMPL.setImportantForAccessibility(view, mode); 1818 } 1819 1820 /** 1821 * Computes whether this view should be exposed for accessibility. In 1822 * general, views that are interactive or provide information are exposed 1823 * while views that serve only as containers are hidden. 1824 * <p> 1825 * If an ancestor of this view has importance 1826 * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, this method 1827 * returns <code>false</code>. 1828 * <p> 1829 * Otherwise, the value is computed according to the view's 1830 * {@link #getImportantForAccessibility(View)} value: 1831 * <ol> 1832 * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_NO} or 1833 * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, return <code>false 1834 * </code> 1835 * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_YES}, return <code>true</code> 1836 * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_AUTO}, return <code>true</code> if 1837 * view satisfies any of the following: 1838 * <ul> 1839 * <li>Is actionable, e.g. {@link View#isClickable()}, 1840 * {@link View#isLongClickable()}, or {@link View#isFocusable()} 1841 * <li>Has an {@link AccessibilityDelegateCompat} 1842 * <li>Has an interaction listener, e.g. {@link View.OnTouchListener}, 1843 * {@link View.OnKeyListener}, etc. 1844 * <li>Is an accessibility live region, e.g. 1845 * {@link #getAccessibilityLiveRegion(View)} is not 1846 * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. 1847 * </ul> 1848 * </ol> 1849 * <p> 1850 * <em>Note:</em> Prior to API 21, this method will always return {@code true}. 1851 * 1852 * @return Whether the view is exposed for accessibility. 1853 * @see #setImportantForAccessibility(View, int) 1854 * @see #getImportantForAccessibility(View) 1855 */ 1856 public static boolean isImportantForAccessibility(View view) { 1857 return IMPL.isImportantForAccessibility(view); 1858 } 1859 1860 /** 1861 * Performs the specified accessibility action on the view. For 1862 * possible accessibility actions look at {@link AccessibilityNodeInfoCompat}. 1863 * <p> 1864 * If an {@link AccessibilityDelegateCompat} has been specified via calling 1865 * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its 1866 * {@link AccessibilityDelegateCompat#performAccessibilityAction(View, int, Bundle)} 1867 * is responsible for handling this call. 1868 * </p> 1869 * 1870 * @param action The action to perform. 1871 * @param arguments Optional action arguments. 1872 * @return Whether the action was performed. 1873 */ 1874 public static boolean performAccessibilityAction(View view, int action, Bundle arguments) { 1875 return IMPL.performAccessibilityAction(view, action, arguments); 1876 } 1877 1878 /** 1879 * Gets the provider for managing a virtual view hierarchy rooted at this View 1880 * and reported to {@link android.accessibilityservice.AccessibilityService}s 1881 * that explore the window content. 1882 * <p> 1883 * If this method returns an instance, this instance is responsible for managing 1884 * {@link AccessibilityNodeInfoCompat}s describing the virtual sub-tree rooted at 1885 * this View including the one representing the View itself. Similarly the returned 1886 * instance is responsible for performing accessibility actions on any virtual 1887 * view or the root view itself. 1888 * </p> 1889 * <p> 1890 * If an {@link AccessibilityDelegateCompat} has been specified via calling 1891 * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its 1892 * {@link AccessibilityDelegateCompat#getAccessibilityNodeProvider(View)} 1893 * is responsible for handling this call. 1894 * </p> 1895 * 1896 * @param view The view whose property to get. 1897 * @return The provider. 1898 * 1899 * @see AccessibilityNodeProviderCompat 1900 */ 1901 public static AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) { 1902 return IMPL.getAccessibilityNodeProvider(view); 1903 } 1904 1905 /** 1906 * The opacity of the view. This is a value from 0 to 1, where 0 means the view is 1907 * completely transparent and 1 means the view is completely opaque. 1908 * 1909 * <p>By default this is 1.0f. 1910 * @return The opacity of the view. 1911 * 1912 * @deprecated Use {@link View#getAlpha()} directly. 1913 */ 1914 @Deprecated 1915 public static float getAlpha(View view) { 1916 return view.getAlpha(); 1917 } 1918 1919 /** 1920 * <p>Specifies the type of layer backing this view. The layer can be 1921 * {@link View#LAYER_TYPE_NONE disabled}, {@link View#LAYER_TYPE_SOFTWARE software} or 1922 * {@link View#LAYER_TYPE_HARDWARE hardware}.</p> 1923 * 1924 * <p>A layer is associated with an optional {@link android.graphics.Paint} 1925 * instance that controls how the layer is composed on screen. The following 1926 * properties of the paint are taken into account when composing the layer:</p> 1927 * <ul> 1928 * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li> 1929 * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li> 1930 * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li> 1931 * </ul> 1932 * 1933 * <p>If this view has an alpha value set to < 1.0 by calling 1934 * setAlpha(float), the alpha value of the layer's paint is replaced by 1935 * this view's alpha value. Calling setAlpha(float) is therefore 1936 * equivalent to setting a hardware layer on this view and providing a paint with 1937 * the desired alpha value.<p> 1938 * 1939 * <p>Refer to the documentation of {@link View#LAYER_TYPE_NONE disabled}, 1940 * {@link View#LAYER_TYPE_SOFTWARE software} and {@link View#LAYER_TYPE_HARDWARE hardware} 1941 * for more information on when and how to use layers.</p> 1942 * 1943 * @param view View to set the layer type for 1944 * @param layerType The type of layer to use with this view, must be one of 1945 * {@link View#LAYER_TYPE_NONE}, {@link View#LAYER_TYPE_SOFTWARE} or 1946 * {@link View#LAYER_TYPE_HARDWARE} 1947 * @param paint The paint used to compose the layer. This argument is optional 1948 * and can be null. It is ignored when the layer type is 1949 * {@link View#LAYER_TYPE_NONE} 1950 * 1951 * @deprecated Use {@link View#setLayerType(int, Paint)} directly. 1952 */ 1953 @Deprecated 1954 public static void setLayerType(View view, @LayerType int layerType, Paint paint) { 1955 view.setLayerType(layerType, paint); 1956 } 1957 1958 /** 1959 * Indicates what type of layer is currently associated with this view. By default 1960 * a view does not have a layer, and the layer type is {@link View#LAYER_TYPE_NONE}. 1961 * Refer to the documentation of 1962 * {@link #setLayerType(android.view.View, int, android.graphics.Paint)} 1963 * for more information on the different types of layers. 1964 * 1965 * @param view The view to fetch the layer type from 1966 * @return {@link View#LAYER_TYPE_NONE}, {@link View#LAYER_TYPE_SOFTWARE} or 1967 * {@link View#LAYER_TYPE_HARDWARE} 1968 * 1969 * @see #setLayerType(android.view.View, int, android.graphics.Paint) 1970 * @see View#LAYER_TYPE_NONE 1971 * @see View#LAYER_TYPE_SOFTWARE 1972 * @see View#LAYER_TYPE_HARDWARE 1973 * 1974 * @deprecated Use {@link View#getLayerType()} directly. 1975 */ 1976 @Deprecated 1977 @LayerType 1978 public static int getLayerType(View view) { 1979 //noinspection ResourceType 1980 return view.getLayerType(); 1981 } 1982 1983 /** 1984 * Gets the id of a view for which a given view serves as a label for 1985 * accessibility purposes. 1986 * 1987 * @param view The view on which to invoke the corresponding method. 1988 * @return The labeled view id. 1989 */ 1990 public static int getLabelFor(View view) { 1991 return IMPL.getLabelFor(view); 1992 } 1993 1994 /** 1995 * Sets the id of a view for which a given view serves as a label for 1996 * accessibility purposes. 1997 * 1998 * @param view The view on which to invoke the corresponding method. 1999 * @param labeledId The labeled view id. 2000 */ 2001 public static void setLabelFor(View view, @IdRes int labeledId) { 2002 IMPL.setLabelFor(view, labeledId); 2003 } 2004 2005 /** 2006 * Updates the {@link Paint} object used with the current layer (used only if the current 2007 * layer type is not set to {@link View#LAYER_TYPE_NONE}). Changed properties of the Paint 2008 * provided to {@link #setLayerType(android.view.View, int, android.graphics.Paint)} 2009 * will be used the next time the View is redrawn, but 2010 * {@link #setLayerPaint(android.view.View, android.graphics.Paint)} 2011 * must be called to ensure that the view gets redrawn immediately. 2012 * 2013 * <p>A layer is associated with an optional {@link android.graphics.Paint} 2014 * instance that controls how the layer is composed on screen. The following 2015 * properties of the paint are taken into account when composing the layer:</p> 2016 * <ul> 2017 * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li> 2018 * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li> 2019 * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li> 2020 * </ul> 2021 * 2022 * <p>If this view has an alpha value set to < 1.0 by calling 2023 * View#setAlpha(float), the alpha value of the layer's paint is replaced by 2024 * this view's alpha value. Calling View#setAlpha(float) is therefore 2025 * equivalent to setting a hardware layer on this view and providing a paint with 2026 * the desired alpha value.</p> 2027 * 2028 * @param view View to set a layer paint for 2029 * @param paint The paint used to compose the layer. This argument is optional 2030 * and can be null. It is ignored when the layer type is 2031 * {@link View#LAYER_TYPE_NONE} 2032 * 2033 * @see #setLayerType(View, int, android.graphics.Paint) 2034 */ 2035 public static void setLayerPaint(View view, Paint paint) { 2036 IMPL.setLayerPaint(view, paint); 2037 } 2038 2039 /** 2040 * Returns the resolved layout direction for this view. 2041 * 2042 * @param view View to get layout direction for 2043 * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns 2044 * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL. 2045 * 2046 * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version 2047 * is lower than Jellybean MR1 (API 17) 2048 */ 2049 @ResolvedLayoutDirectionMode 2050 public static int getLayoutDirection(View view) { 2051 //noinspection ResourceType 2052 return IMPL.getLayoutDirection(view); 2053 } 2054 2055 /** 2056 * Set the layout direction for this view. This will propagate a reset of layout direction 2057 * resolution to the view's children and resolve layout direction for this view. 2058 * 2059 * @param view View to set layout direction for 2060 * @param layoutDirection the layout direction to set. Should be one of: 2061 * 2062 * {@link #LAYOUT_DIRECTION_LTR}, 2063 * {@link #LAYOUT_DIRECTION_RTL}, 2064 * {@link #LAYOUT_DIRECTION_INHERIT}, 2065 * {@link #LAYOUT_DIRECTION_LOCALE}. 2066 * 2067 * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution 2068 * proceeds up the parent chain of the view to get the value. If there is no parent, then it 2069 * will return the default {@link #LAYOUT_DIRECTION_LTR}. 2070 */ 2071 public static void setLayoutDirection(View view, @LayoutDirectionMode int layoutDirection) { 2072 IMPL.setLayoutDirection(view, layoutDirection); 2073 } 2074 2075 /** 2076 * Gets the parent for accessibility purposes. Note that the parent for 2077 * accessibility is not necessary the immediate parent. It is the first 2078 * predecessor that is important for accessibility. 2079 * 2080 * @param view View to retrieve parent for 2081 * @return The parent for use in accessibility inspection 2082 */ 2083 public static ViewParent getParentForAccessibility(View view) { 2084 return IMPL.getParentForAccessibility(view); 2085 } 2086 2087 /** 2088 * Indicates whether this View is opaque. An opaque View guarantees that it will 2089 * draw all the pixels overlapping its bounds using a fully opaque color. 2090 * 2091 * @return True if this View is guaranteed to be fully opaque, false otherwise. 2092 * @deprecated Use {@link View#isOpaque()} directly. This method will be 2093 * removed in a future release. 2094 */ 2095 @Deprecated 2096 public static boolean isOpaque(View view) { 2097 return view.isOpaque(); 2098 } 2099 2100 /** 2101 * Utility to reconcile a desired size and state, with constraints imposed 2102 * by a MeasureSpec. Will take the desired size, unless a different size 2103 * is imposed by the constraints. The returned value is a compound integer, 2104 * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and 2105 * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting 2106 * size is smaller than the size the view wants to be. 2107 * 2108 * @param size How big the view wants to be 2109 * @param measureSpec Constraints imposed by the parent 2110 * @return Size information bit mask as defined by 2111 * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}. 2112 * 2113 * @deprecated Use {@link View#resolveSizeAndState(int, int, int)} directly. 2114 */ 2115 @Deprecated 2116 public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) { 2117 return View.resolveSizeAndState(size, measureSpec, childMeasuredState); 2118 } 2119 2120 /** 2121 * Return the full width measurement information for this view as computed 2122 * by the most recent call to {@link android.view.View#measure(int, int)}. 2123 * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and 2124 * {@link #MEASURED_STATE_TOO_SMALL}. 2125 * This should be used during measurement and layout calculations only. Use 2126 * {@link android.view.View#getWidth()} to see how wide a view is after layout. 2127 * 2128 * @return The measured width of this view as a bit mask. 2129 * 2130 * @deprecated Use {@link View#getMeasuredWidth()} directly. 2131 */ 2132 @Deprecated 2133 public static int getMeasuredWidthAndState(View view) { 2134 return view.getMeasuredWidthAndState(); 2135 } 2136 2137 /** 2138 * Return the full height measurement information for this view as computed 2139 * by the most recent call to {@link android.view.View#measure(int, int)}. 2140 * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and 2141 * {@link #MEASURED_STATE_TOO_SMALL}. 2142 * This should be used during measurement and layout calculations only. Use 2143 * {@link android.view.View#getHeight()} to see how wide a view is after layout. 2144 * 2145 * @return The measured width of this view as a bit mask. 2146 * 2147 * @deprecated Use {@link View#getMeasuredHeightAndState()} directly. 2148 */ 2149 @Deprecated 2150 public static int getMeasuredHeightAndState(View view) { 2151 return view.getMeasuredHeightAndState(); 2152 } 2153 2154 /** 2155 * Return only the state bits of {@link #getMeasuredWidthAndState} 2156 * and {@link #getMeasuredHeightAndState}, combined into one integer. 2157 * The width component is in the regular bits {@link #MEASURED_STATE_MASK} 2158 * and the height component is at the shifted bits 2159 * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}. 2160 * 2161 * @deprecated Use {@link View#getMeasuredState()} directly. 2162 */ 2163 @Deprecated 2164 public static int getMeasuredState(View view) { 2165 return view.getMeasuredState(); 2166 } 2167 2168 /** 2169 * Merge two states as returned by {@link #getMeasuredState(View)}. 2170 * @param curState The current state as returned from a view or the result 2171 * of combining multiple views. 2172 * @param newState The new view state to combine. 2173 * @return Returns a new integer reflecting the combination of the two 2174 * states. 2175 * 2176 * @deprecated Use {@link View#combineMeasuredStates(int, int)} directly. 2177 */ 2178 @Deprecated 2179 public static int combineMeasuredStates(int curState, int newState) { 2180 return View.combineMeasuredStates(curState, newState); 2181 } 2182 2183 /** 2184 * Gets the live region mode for the specified View. 2185 * 2186 * @param view The view from which to obtain the live region mode 2187 * @return The live region mode for the view. 2188 * 2189 * @see ViewCompat#setAccessibilityLiveRegion(View, int) 2190 */ 2191 @AccessibilityLiveRegion 2192 public static int getAccessibilityLiveRegion(View view) { 2193 //noinspection ResourceType 2194 return IMPL.getAccessibilityLiveRegion(view); 2195 } 2196 2197 /** 2198 * Sets the live region mode for the specified view. This indicates to 2199 * accessibility services whether they should automatically notify the user 2200 * about changes to the view's content description or text, or to the 2201 * content descriptions or text of the view's children (where applicable). 2202 * <p> 2203 * For example, in a login screen with a TextView that displays an "incorrect 2204 * password" notification, that view should be marked as a live region with 2205 * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}. 2206 * <p> 2207 * To disable change notifications for this view, use 2208 * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region 2209 * mode for most views. 2210 * <p> 2211 * To indicate that the user should be notified of changes, use 2212 * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}. 2213 * <p> 2214 * If the view's changes should interrupt ongoing speech and notify the user 2215 * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}. 2216 * 2217 * @param view The view on which to set the live region mode 2218 * @param mode The live region mode for this view, one of: 2219 * <ul> 2220 * <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE} 2221 * <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE} 2222 * <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE} 2223 * </ul> 2224 */ 2225 public static void setAccessibilityLiveRegion(View view, @AccessibilityLiveRegion int mode) { 2226 IMPL.setAccessibilityLiveRegion(view, mode); 2227 } 2228 2229 /** 2230 * Returns the start padding of the specified view depending on its resolved layout direction. 2231 * If there are inset and enabled scrollbars, this value may include the space 2232 * required to display the scrollbars as well. 2233 * 2234 * @param view The view to get padding for 2235 * @return the start padding in pixels 2236 */ 2237 public static int getPaddingStart(View view) { 2238 return IMPL.getPaddingStart(view); 2239 } 2240 2241 /** 2242 * Returns the end padding of the specified view depending on its resolved layout direction. 2243 * If there are inset and enabled scrollbars, this value may include the space 2244 * required to display the scrollbars as well. 2245 * 2246 * @param view The view to get padding for 2247 * @return the end padding in pixels 2248 */ 2249 public static int getPaddingEnd(View view) { 2250 return IMPL.getPaddingEnd(view); 2251 } 2252 2253 /** 2254 * Sets the relative padding. The view may add on the space required to display 2255 * the scrollbars, depending on the style and visibility of the scrollbars. 2256 * So the values returned from {@link #getPaddingStart}, {@link View#getPaddingTop}, 2257 * {@link #getPaddingEnd} and {@link View#getPaddingBottom} may be different 2258 * from the values set in this call. 2259 * 2260 * @param view The view on which to set relative padding 2261 * @param start the start padding in pixels 2262 * @param top the top padding in pixels 2263 * @param end the end padding in pixels 2264 * @param bottom the bottom padding in pixels 2265 */ 2266 public static void setPaddingRelative(View view, int start, int top, int end, int bottom) { 2267 IMPL.setPaddingRelative(view, start, top, end, bottom); 2268 } 2269 2270 /** 2271 * Notify a view that it is being temporarily detached. 2272 */ 2273 public static void dispatchStartTemporaryDetach(View view) { 2274 IMPL.dispatchStartTemporaryDetach(view); 2275 } 2276 2277 /** 2278 * Notify a view that its temporary detach has ended; the view is now reattached. 2279 */ 2280 public static void dispatchFinishTemporaryDetach(View view) { 2281 IMPL.dispatchFinishTemporaryDetach(view); 2282 } 2283 2284 /** 2285 * The horizontal location of this view relative to its {@link View#getLeft() left} position. 2286 * This position is post-layout, in addition to wherever the object's 2287 * layout placed it. 2288 * 2289 * @return The horizontal position of this view relative to its left position, in pixels. 2290 * 2291 * @deprecated Use {@link View#getTranslationX()} directly. 2292 */ 2293 @Deprecated 2294 public static float getTranslationX(View view) { 2295 return view.getTranslationX(); 2296 } 2297 2298 /** 2299 * The vertical location of this view relative to its {@link View#getTop() top} position. 2300 * This position is post-layout, in addition to wherever the object's 2301 * layout placed it. 2302 * 2303 * @return The vertical position of this view relative to its top position, in pixels. 2304 * 2305 * @deprecated Use {@link View#getTranslationY()} directly. 2306 */ 2307 @Deprecated 2308 public static float getTranslationY(View view) { 2309 return view.getTranslationY(); 2310 } 2311 2312 /** 2313 * The transform matrix of this view, which is calculated based on the current 2314 * rotation, scale, and pivot properties. 2315 * <p> 2316 * 2317 * @param view The view whose Matrix will be returned 2318 * @return The current transform matrix for the view 2319 * 2320 * @see #getRotation(View) 2321 * @see #getScaleX(View) 2322 * @see #getScaleY(View) 2323 * @see #getPivotX(View) 2324 * @see #getPivotY(View) 2325 * 2326 * @deprecated Use {@link View#getMatrix()} directly. 2327 */ 2328 @Deprecated 2329 @Nullable 2330 public static Matrix getMatrix(View view) { 2331 return view.getMatrix(); 2332 } 2333 2334 /** 2335 * Returns the minimum width of the view. 2336 * 2337 * <p>Prior to API 16 this will return 0.</p> 2338 * 2339 * @return the minimum width the view will try to be. 2340 */ 2341 public static int getMinimumWidth(View view) { 2342 return IMPL.getMinimumWidth(view); 2343 } 2344 2345 /** 2346 * Returns the minimum height of the view. 2347 * 2348 * <p>Prior to API 16 this will return 0.</p> 2349 * 2350 * @return the minimum height the view will try to be. 2351 */ 2352 public static int getMinimumHeight(View view) { 2353 return IMPL.getMinimumHeight(view); 2354 } 2355 2356 /** 2357 * This method returns a ViewPropertyAnimator object, which can be used to animate 2358 * specific properties on this View. 2359 * 2360 * <p>Prior to API 14, this method will do nothing.</p> 2361 * 2362 * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View. 2363 */ 2364 public static ViewPropertyAnimatorCompat animate(View view) { 2365 return IMPL.animate(view); 2366 } 2367 2368 /** 2369 * Sets the horizontal location of this view relative to its left position. 2370 * This effectively positions the object post-layout, in addition to wherever the object's 2371 * layout placed it. 2372 * 2373 * @param value The horizontal position of this view relative to its left position, 2374 * in pixels. 2375 * 2376 * @deprecated Use {@link View#setTranslationX(float)} directly. 2377 */ 2378 @Deprecated 2379 public static void setTranslationX(View view, float value) { 2380 view.setTranslationX(value); 2381 } 2382 2383 /** 2384 * Sets the vertical location of this view relative to its top position. 2385 * This effectively positions the object post-layout, in addition to wherever the object's 2386 * layout placed it. 2387 * 2388 * @param value The vertical position of this view relative to its top position, 2389 * in pixels. 2390 * 2391 * @attr name android:translationY 2392 * 2393 * @deprecated Use {@link View#setTranslationY(float)} directly. 2394 */ 2395 @Deprecated 2396 public static void setTranslationY(View view, float value) { 2397 view.setTranslationY(value); 2398 } 2399 2400 /** 2401 * <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is 2402 * completely transparent and 1 means the view is completely opaque.</p> 2403 * 2404 * <p> Note that setting alpha to a translucent value (0 < alpha < 1) can have significant 2405 * performance implications, especially for large views. It is best to use the alpha property 2406 * sparingly and transiently, as in the case of fading animations.</p> 2407 * 2408 * @param value The opacity of the view. 2409 * 2410 * @deprecated Use {@link View#setAlpha(float)} directly. 2411 */ 2412 @Deprecated 2413 public static void setAlpha(View view, @FloatRange(from=0.0, to=1.0) float value) { 2414 view.setAlpha(value); 2415 } 2416 2417 /** 2418 * Sets the visual x position of this view, in pixels. This is equivalent to setting the 2419 * {@link #setTranslationX(View, float) translationX} property to be the difference between 2420 * the x value passed in and the current left property of the view as determined 2421 * by the layout bounds. 2422 * 2423 * @param value The visual x position of this view, in pixels. 2424 * 2425 * @deprecated Use {@link View#setX(float)} directly. 2426 */ 2427 @Deprecated 2428 public static void setX(View view, float value) { 2429 view.setX(value); 2430 } 2431 2432 /** 2433 * Sets the visual y position of this view, in pixels. This is equivalent to setting the 2434 * {@link #setTranslationY(View, float) translationY} property to be the difference between 2435 * the y value passed in and the current top property of the view as determined by the 2436 * layout bounds. 2437 * 2438 * @param value The visual y position of this view, in pixels. 2439 * 2440 * @deprecated Use {@link View#setY(float)} directly. 2441 */ 2442 @Deprecated 2443 public static void setY(View view, float value) { 2444 view.setY(value); 2445 } 2446 2447 /** 2448 * Sets the degrees that the view is rotated around the pivot point. Increasing values 2449 * result in clockwise rotation. 2450 * 2451 * @param value The degrees of rotation. 2452 * 2453 * @deprecated Use {@link View#setRotation(float)} directly. 2454 */ 2455 @Deprecated 2456 public static void setRotation(View view, float value) { 2457 view.setRotation(value); 2458 } 2459 2460 /** 2461 * Sets the degrees that the view is rotated around the horizontal axis through the pivot point. 2462 * Increasing values result in clockwise rotation from the viewpoint of looking down the 2463 * x axis. 2464 * 2465 * @param value The degrees of X rotation. 2466 * 2467 * @deprecated Use {@link View#setRotationX(float)} directly. 2468 */ 2469 @Deprecated 2470 public static void setRotationX(View view, float value) { 2471 view.setRotationX(value); 2472 } 2473 2474 /** 2475 * Sets the degrees that the view is rotated around the vertical axis through the pivot point. 2476 * Increasing values result in counter-clockwise rotation from the viewpoint of looking 2477 * down the y axis. 2478 * 2479 * @param value The degrees of Y rotation. 2480 * 2481 * @deprecated Use {@link View#setRotationY(float)} directly. 2482 */ 2483 @Deprecated 2484 public static void setRotationY(View view, float value) { 2485 view.setRotationY(value); 2486 } 2487 2488 /** 2489 * Sets the amount that the view is scaled in x around the pivot point, as a proportion of 2490 * the view's unscaled width. A value of 1 means that no scaling is applied. 2491 * 2492 * @param value The scaling factor. 2493 * 2494 * @deprecated Use {@link View#setScaleX(float)} directly. 2495 */ 2496 @Deprecated 2497 public static void setScaleX(View view, float value) { 2498 view.setScaleX(value); 2499 } 2500 2501 /** 2502 * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of 2503 * the view's unscaled width. A value of 1 means that no scaling is applied. 2504 * 2505 * @param value The scaling factor. 2506 * 2507 * @deprecated Use {@link View#setScaleY(float)} directly. 2508 */ 2509 @Deprecated 2510 public static void setScaleY(View view, float value) { 2511 view.setScaleY(value); 2512 } 2513 2514 /** 2515 * The x location of the point around which the view is 2516 * {@link #setRotation(View, float) rotated} and {@link #setScaleX(View, float) scaled}. 2517 * 2518 * @deprecated Use {@link View#getPivotX()} directly. 2519 */ 2520 @Deprecated 2521 public static float getPivotX(View view) { 2522 return view.getPivotX(); 2523 } 2524 2525 /** 2526 * Sets the x location of the point around which the view is 2527 * {@link #setRotation(View, float) rotated} and {@link #setScaleX(View, float) scaled}. 2528 * By default, the pivot point is centered on the object. 2529 * Setting this property disables this behavior and causes the view to use only the 2530 * explicitly set pivotX and pivotY values. 2531 * 2532 * @param value The x location of the pivot point. 2533 * 2534 * @deprecated Use {@link View#setPivotX(float)} directly. 2535 */ 2536 @Deprecated 2537 public static void setPivotX(View view, float value) { 2538 view.setPivotX(value); 2539 } 2540 2541 /** 2542 * The y location of the point around which the view is {@link #setRotation(View, 2543 * float) rotated} and {@link #setScaleY(View, float) scaled}. 2544 * 2545 * @return The y location of the pivot point. 2546 * 2547 * @deprecated Use {@link View#getPivotY()} directly. 2548 */ 2549 @Deprecated 2550 public static float getPivotY(View view) { 2551 return view.getPivotY(); 2552 } 2553 2554 /** 2555 * Sets the y location of the point around which the view is 2556 * {@link #setRotation(View, float) rotated} and {@link #setScaleY(View, float) scaled}. 2557 * By default, the pivot point is centered on the object. 2558 * Setting this property disables this behavior and causes the view to use only the 2559 * explicitly set pivotX and pivotY values. 2560 * 2561 * @param value The y location of the pivot point. 2562 * 2563 * @deprecated Use {@link View#setPivotX(float)} directly. 2564 */ 2565 @Deprecated 2566 public static void setPivotY(View view, float value) { 2567 view.setPivotY(value); 2568 } 2569 2570 /** 2571 * @deprecated Use {@link View#getRotation()} directly. 2572 */ 2573 @Deprecated 2574 public static float getRotation(View view) { 2575 return view.getRotation(); 2576 } 2577 2578 /** 2579 * @deprecated Use {@link View#getRotationX()} directly. 2580 */ 2581 @Deprecated 2582 public static float getRotationX(View view) { 2583 return view.getRotationX(); 2584 } 2585 2586 /** 2587 * @deprecated Use {@link View#getRotationY()} directly. 2588 */ 2589 @Deprecated 2590 public static float getRotationY(View view) { 2591 return view.getRotationY(); 2592 } 2593 2594 /** 2595 * @deprecated Use {@link View#getScaleX()} directly. 2596 */ 2597 @Deprecated 2598 public static float getScaleX(View view) { 2599 return view.getScaleX(); 2600 } 2601 2602 /** 2603 * @deprecated Use {@link View#getScaleY()} directly. 2604 */ 2605 @Deprecated 2606 public static float getScaleY(View view) { 2607 return view.getScaleY(); 2608 } 2609 2610 /** 2611 * @deprecated Use {@link View#getX()} directly. 2612 */ 2613 @Deprecated 2614 public static float getX(View view) { 2615 return view.getX(); 2616 } 2617 2618 /** 2619 * @deprecated Use {@link View#getY()} directly. 2620 */ 2621 @Deprecated 2622 public static float getY(View view) { 2623 return view.getY(); 2624 } 2625 2626 /** 2627 * Sets the base elevation of this view, in pixels. 2628 */ 2629 public static void setElevation(View view, float elevation) { 2630 IMPL.setElevation(view, elevation); 2631 } 2632 2633 /** 2634 * The base elevation of this view relative to its parent, in pixels. 2635 * 2636 * @return The base depth position of the view, in pixels. 2637 */ 2638 public static float getElevation(View view) { 2639 return IMPL.getElevation(view); 2640 } 2641 2642 /** 2643 * Sets the depth location of this view relative to its {@link #getElevation(View) elevation}. 2644 */ 2645 public static void setTranslationZ(View view, float translationZ) { 2646 IMPL.setTranslationZ(view, translationZ); 2647 } 2648 2649 /** 2650 * The depth location of this view relative to its {@link #getElevation(View) elevation}. 2651 * 2652 * @return The depth of this view relative to its elevation. 2653 */ 2654 public static float getTranslationZ(View view) { 2655 return IMPL.getTranslationZ(view); 2656 } 2657 2658 /** 2659 * Sets the name of the View to be used to identify Views in Transitions. 2660 * Names should be unique in the View hierarchy. 2661 * 2662 * @param view The View against which to invoke the method. 2663 * @param transitionName The name of the View to uniquely identify it for Transitions. 2664 */ 2665 public static void setTransitionName(View view, String transitionName) { 2666 IMPL.setTransitionName(view, transitionName); 2667 } 2668 2669 /** 2670 * Returns the name of the View to be used to identify Views in Transitions. 2671 * Names should be unique in the View hierarchy. 2672 * 2673 * <p>This returns null if the View has not been given a name.</p> 2674 * 2675 * @param view The View against which to invoke the method. 2676 * @return The name used of the View to be used to identify Views in Transitions or null 2677 * if no name has been given. 2678 */ 2679 public static String getTransitionName(View view) { 2680 return IMPL.getTransitionName(view); 2681 } 2682 2683 /** 2684 * Returns the current system UI visibility that is currently set for the entire window. 2685 */ 2686 public static int getWindowSystemUiVisibility(View view) { 2687 return IMPL.getWindowSystemUiVisibility(view); 2688 } 2689 2690 /** 2691 * Ask that a new dispatch of {@code View.onApplyWindowInsets(WindowInsets)} be performed. This 2692 * falls back to {@code View.requestFitSystemWindows()} where available. 2693 */ 2694 public static void requestApplyInsets(View view) { 2695 IMPL.requestApplyInsets(view); 2696 } 2697 2698 /** 2699 * Tells the ViewGroup whether to draw its children in the order defined by the method 2700 * {@code ViewGroup.getChildDrawingOrder(int, int)}. 2701 * 2702 * @param enabled true if the order of the children when drawing is determined by 2703 * {@link ViewGroup#getChildDrawingOrder(int, int)}, false otherwise 2704 * 2705 * <p>Prior to API 7 this will have no effect.</p> 2706 */ 2707 public static void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) { 2708 IMPL.setChildrenDrawingOrderEnabled(viewGroup, enabled); 2709 } 2710 2711 /** 2712 * Returns true if this view should adapt to fit system window insets. This method will always 2713 * return false before API 16 (Jellybean). 2714 */ 2715 public static boolean getFitsSystemWindows(View v) { 2716 return IMPL.getFitsSystemWindows(v); 2717 } 2718 2719 /** 2720 * Sets whether or not this view should account for system screen decorations 2721 * such as the status bar and inset its content; that is, controlling whether 2722 * the default implementation of {@link View#fitSystemWindows(Rect)} will be 2723 * executed. See that method for more details. 2724 * 2725 * @deprecated Use {@link View#setFitsSystemWindows(boolean)} directly. 2726 */ 2727 @Deprecated 2728 public static void setFitsSystemWindows(View view, boolean fitSystemWindows) { 2729 view.setFitsSystemWindows(fitSystemWindows); 2730 } 2731 2732 /** 2733 * On API 11 devices and above, call <code>Drawable.jumpToCurrentState()</code> 2734 * on all Drawable objects associated with this view. 2735 * <p> 2736 * On API 21 and above, also calls <code>StateListAnimator#jumpToCurrentState()</code> 2737 * if there is a StateListAnimator attached to this view. 2738 * 2739 * @deprecated Use {@link View#jumpDrawablesToCurrentState()} directly. 2740 */ 2741 @Deprecated 2742 public static void jumpDrawablesToCurrentState(View v) { 2743 v.jumpDrawablesToCurrentState(); 2744 } 2745 2746 /** 2747 * Set an {@link OnApplyWindowInsetsListener} to take over the policy for applying 2748 * window insets to this view. This will only take effect on devices with API 21 or above. 2749 */ 2750 public static void setOnApplyWindowInsetsListener(View v, 2751 OnApplyWindowInsetsListener listener) { 2752 IMPL.setOnApplyWindowInsetsListener(v, listener); 2753 } 2754 2755 /** 2756 * Called when the view should apply {@link WindowInsetsCompat} according to its internal policy. 2757 * 2758 * <p>Clients may supply an {@link OnApplyWindowInsetsListener} to a view. If one is set 2759 * it will be called during dispatch instead of this method. The listener may optionally 2760 * call this method from its own implementation if it wishes to apply the view's default 2761 * insets policy in addition to its own.</p> 2762 * 2763 * @param view The View against which to invoke the method. 2764 * @param insets Insets to apply 2765 * @return The supplied insets with any applied insets consumed 2766 */ 2767 public static WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) { 2768 return IMPL.onApplyWindowInsets(view, insets); 2769 } 2770 2771 /** 2772 * Request to apply the given window insets to this view or another view in its subtree. 2773 * 2774 * <p>This method should be called by clients wishing to apply insets corresponding to areas 2775 * obscured by window decorations or overlays. This can include the status and navigation bars, 2776 * action bars, input methods and more. New inset categories may be added in the future. 2777 * The method returns the insets provided minus any that were applied by this view or its 2778 * children.</p> 2779 * 2780 * @param insets Insets to apply 2781 * @return The provided insets minus the insets that were consumed 2782 */ 2783 public static WindowInsetsCompat dispatchApplyWindowInsets(View view, 2784 WindowInsetsCompat insets) { 2785 return IMPL.dispatchApplyWindowInsets(view, insets); 2786 } 2787 2788 /** 2789 * Controls whether the entire hierarchy under this view will save its 2790 * state when a state saving traversal occurs from its parent. 2791 * 2792 * @param enabled Set to false to <em>disable</em> state saving, or true 2793 * (the default) to allow it. 2794 * 2795 * @deprecated Use {@link View#setSaveFromParentEnabled(boolean)} directly. 2796 */ 2797 @Deprecated 2798 public static void setSaveFromParentEnabled(View v, boolean enabled) { 2799 v.setSaveFromParentEnabled(enabled); 2800 } 2801 2802 /** 2803 * Changes the activated state of this view. A view can be activated or not. 2804 * Note that activation is not the same as selection. Selection is 2805 * a transient property, representing the view (hierarchy) the user is 2806 * currently interacting with. Activation is a longer-term state that the 2807 * user can move views in and out of. 2808 * 2809 * @param activated true if the view must be activated, false otherwise 2810 * 2811 * @deprecated Use {@link View#setActivated(boolean)} directly. 2812 */ 2813 @Deprecated 2814 public static void setActivated(View view, boolean activated) { 2815 view.setActivated(activated); 2816 } 2817 2818 /** 2819 * Returns whether this View has content which overlaps. 2820 * 2821 * <p>This function, intended to be overridden by specific View types, is an optimization when 2822 * alpha is set on a view. If rendering overlaps in a view with alpha < 1, that view is drawn to 2823 * an offscreen buffer and then composited into place, which can be expensive. If the view has 2824 * no overlapping rendering, the view can draw each primitive with the appropriate alpha value 2825 * directly. An example of overlapping rendering is a TextView with a background image, such as 2826 * a Button. An example of non-overlapping rendering is a TextView with no background, or an 2827 * ImageView with only the foreground image. The default implementation returns true; subclasses 2828 * should override if they have cases which can be optimized.</p> 2829 * 2830 * @return true if the content in this view might overlap, false otherwise. 2831 */ 2832 public static boolean hasOverlappingRendering(View view) { 2833 return IMPL.hasOverlappingRendering(view); 2834 } 2835 2836 /** 2837 * Return if the padding as been set through relative values 2838 * {@code View.setPaddingRelative(int, int, int, int)} or thru 2839 * 2840 * @return true if the padding is relative or false if it is not. 2841 */ 2842 public static boolean isPaddingRelative(View view) { 2843 return IMPL.isPaddingRelative(view); 2844 } 2845 2846 /** 2847 * Set the background of the {@code view} to a given Drawable, or remove the background. If the 2848 * background has padding, {@code view}'s padding is set to the background's padding. However, 2849 * when a background is removed, this View's padding isn't touched. If setting the padding is 2850 * desired, please use{@code setPadding(int, int, int, int)}. 2851 */ 2852 public static void setBackground(View view, Drawable background) { 2853 IMPL.setBackground(view, background); 2854 } 2855 2856 /** 2857 * Return the tint applied to the background drawable, if specified. 2858 * <p> 2859 * Only returns meaningful info when running on API v21 or newer, or if {@code view} 2860 * implements the {@code TintableBackgroundView} interface. 2861 */ 2862 public static ColorStateList getBackgroundTintList(View view) { 2863 return IMPL.getBackgroundTintList(view); 2864 } 2865 2866 /** 2867 * Applies a tint to the background drawable. 2868 * <p> 2869 * This will always take effect when running on API v21 or newer. When running on platforms 2870 * previous to API v21, it will only take effect if {@code view} implement the 2871 * {@code TintableBackgroundView} interface. 2872 */ 2873 public static void setBackgroundTintList(View view, ColorStateList tintList) { 2874 IMPL.setBackgroundTintList(view, tintList); 2875 } 2876 2877 /** 2878 * Return the blending mode used to apply the tint to the background 2879 * drawable, if specified. 2880 * <p> 2881 * Only returns meaningful info when running on API v21 or newer, or if {@code view} 2882 * implements the {@code TintableBackgroundView} interface. 2883 */ 2884 public static PorterDuff.Mode getBackgroundTintMode(View view) { 2885 return IMPL.getBackgroundTintMode(view); 2886 } 2887 2888 /** 2889 * Specifies the blending mode used to apply the tint specified by 2890 * {@link #setBackgroundTintList(android.view.View, android.content.res.ColorStateList)} to 2891 * the background drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}. 2892 * <p> 2893 * This will always take effect when running on API v21 or newer. When running on platforms 2894 * previous to API v21, it will only take effect if {@code view} implement the 2895 * {@code TintableBackgroundView} interface. 2896 */ 2897 public static void setBackgroundTintMode(View view, PorterDuff.Mode mode) { 2898 IMPL.setBackgroundTintMode(view, mode); 2899 } 2900 // TODO: getters for various view properties (rotation, etc) 2901 2902 /** 2903 * Enable or disable nested scrolling for this view. 2904 * 2905 * <p>If this property is set to true the view will be permitted to initiate nested 2906 * scrolling operations with a compatible parent view in the current hierarchy. If this 2907 * view does not implement nested scrolling this will have no effect. Disabling nested scrolling 2908 * while a nested scroll is in progress has the effect of 2909 * {@link #stopNestedScroll(View) stopping} the nested scroll.</p> 2910 * 2911 * @param enabled true to enable nested scrolling, false to disable 2912 * 2913 * @see #isNestedScrollingEnabled(View) 2914 */ 2915 public static void setNestedScrollingEnabled(View view, boolean enabled) { 2916 IMPL.setNestedScrollingEnabled(view, enabled); 2917 } 2918 2919 /** 2920 * Returns true if nested scrolling is enabled for this view. 2921 * 2922 * <p>If nested scrolling is enabled and this View class implementation supports it, 2923 * this view will act as a nested scrolling child view when applicable, forwarding data 2924 * about the scroll operation in progress to a compatible and cooperating nested scrolling 2925 * parent.</p> 2926 * 2927 * @return true if nested scrolling is enabled 2928 * 2929 * @see #setNestedScrollingEnabled(View, boolean) 2930 */ 2931 public static boolean isNestedScrollingEnabled(View view) { 2932 return IMPL.isNestedScrollingEnabled(view); 2933 } 2934 2935 /** 2936 * Begin a nestable scroll operation along the given axes. 2937 * 2938 * <p>A view starting a nested scroll promises to abide by the following contract:</p> 2939 * 2940 * <p>The view will call startNestedScroll upon initiating a scroll operation. In the case 2941 * of a touch scroll this corresponds to the initial {@link MotionEvent#ACTION_DOWN}. 2942 * In the case of touch scrolling the nested scroll will be terminated automatically in 2943 * the same manner as {@link ViewParent#requestDisallowInterceptTouchEvent(boolean)}. 2944 * In the event of programmatic scrolling the caller must explicitly call 2945 * {@link #stopNestedScroll(View)} to indicate the end of the nested scroll.</p> 2946 * 2947 * <p>If <code>startNestedScroll</code> returns true, a cooperative parent was found. 2948 * If it returns false the caller may ignore the rest of this contract until the next scroll. 2949 * Calling startNestedScroll while a nested scroll is already in progress will return true.</p> 2950 * 2951 * <p>At each incremental step of the scroll the caller should invoke 2952 * {@link #dispatchNestedPreScroll(View, int, int, int[], int[]) dispatchNestedPreScroll} 2953 * once it has calculated the requested scrolling delta. If it returns true the nested scrolling 2954 * parent at least partially consumed the scroll and the caller should adjust the amount it 2955 * scrolls by.</p> 2956 * 2957 * <p>After applying the remainder of the scroll delta the caller should invoke 2958 * {@link #dispatchNestedScroll(View, int, int, int, int, int[]) dispatchNestedScroll}, passing 2959 * both the delta consumed and the delta unconsumed. A nested scrolling parent may treat 2960 * these values differently. See 2961 * {@link NestedScrollingParent#onNestedScroll(View, int, int, int, int)}. 2962 * </p> 2963 * 2964 * @param axes Flags consisting of a combination of {@link ViewCompat#SCROLL_AXIS_HORIZONTAL} 2965 * and/or {@link ViewCompat#SCROLL_AXIS_VERTICAL}. 2966 * @return true if a cooperative parent was found and nested scrolling has been enabled for 2967 * the current gesture. 2968 * 2969 * @see #stopNestedScroll(View) 2970 * @see #dispatchNestedPreScroll(View, int, int, int[], int[]) 2971 * @see #dispatchNestedScroll(View, int, int, int, int, int[]) 2972 */ 2973 public static boolean startNestedScroll(View view, int axes) { 2974 return IMPL.startNestedScroll(view, axes); 2975 } 2976 2977 /** 2978 * Stop a nested scroll in progress. 2979 * 2980 * <p>Calling this method when a nested scroll is not currently in progress is harmless.</p> 2981 * 2982 * @see #startNestedScroll(View, int) 2983 */ 2984 public static void stopNestedScroll(View view) { 2985 IMPL.stopNestedScroll(view); 2986 } 2987 2988 /** 2989 * Returns true if this view has a nested scrolling parent. 2990 * 2991 * <p>The presence of a nested scrolling parent indicates that this view has initiated 2992 * a nested scroll and it was accepted by an ancestor view further up the view hierarchy.</p> 2993 * 2994 * @return whether this view has a nested scrolling parent 2995 */ 2996 public static boolean hasNestedScrollingParent(View view) { 2997 return IMPL.hasNestedScrollingParent(view); 2998 } 2999 3000 /** 3001 * Dispatch one step of a nested scroll in progress. 3002 * 3003 * <p>Implementations of views that support nested scrolling should call this to report 3004 * info about a scroll in progress to the current nested scrolling parent. If a nested scroll 3005 * is not currently in progress or nested scrolling is not 3006 * {@link #isNestedScrollingEnabled(View) enabled} for this view this method does nothing.</p> 3007 * 3008 * <p>Compatible View implementations should also call 3009 * {@link #dispatchNestedPreScroll(View, int, int, int[], int[]) dispatchNestedPreScroll} before 3010 * consuming a component of the scroll event themselves.</p> 3011 * 3012 * @param dxConsumed Horizontal distance in pixels consumed by this view during this scroll step 3013 * @param dyConsumed Vertical distance in pixels consumed by this view during this scroll step 3014 * @param dxUnconsumed Horizontal scroll distance in pixels not consumed by this view 3015 * @param dyUnconsumed Horizontal scroll distance in pixels not consumed by this view 3016 * @param offsetInWindow Optional. If not null, on return this will contain the offset 3017 * in local view coordinates of this view from before this operation 3018 * to after it completes. View implementations may use this to adjust 3019 * expected input coordinate tracking. 3020 * @return true if the event was dispatched, false if it could not be dispatched. 3021 * @see #dispatchNestedPreScroll(View, int, int, int[], int[]) 3022 */ 3023 public static boolean dispatchNestedScroll(View view, int dxConsumed, int dyConsumed, 3024 int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { 3025 return IMPL.dispatchNestedScroll(view, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, 3026 offsetInWindow); 3027 } 3028 3029 /** 3030 * Dispatch one step of a nested scroll in progress before this view consumes any portion of it. 3031 * 3032 * <p>Nested pre-scroll events are to nested scroll events what touch intercept is to touch. 3033 * <code>dispatchNestedPreScroll</code> offers an opportunity for the parent view in a nested 3034 * scrolling operation to consume some or all of the scroll operation before the child view 3035 * consumes it.</p> 3036 * 3037 * @param dx Horizontal scroll distance in pixels 3038 * @param dy Vertical scroll distance in pixels 3039 * @param consumed Output. If not null, consumed[0] will contain the consumed component of dx 3040 * and consumed[1] the consumed dy. 3041 * @param offsetInWindow Optional. If not null, on return this will contain the offset 3042 * in local view coordinates of this view from before this operation 3043 * to after it completes. View implementations may use this to adjust 3044 * expected input coordinate tracking. 3045 * @return true if the parent consumed some or all of the scroll delta 3046 * @see #dispatchNestedScroll(View, int, int, int, int, int[]) 3047 */ 3048 public static boolean dispatchNestedPreScroll(View view, int dx, int dy, int[] consumed, 3049 int[] offsetInWindow) { 3050 return IMPL.dispatchNestedPreScroll(view, dx, dy, consumed, offsetInWindow); 3051 } 3052 3053 /** 3054 * Dispatch a fling to a nested scrolling parent. 3055 * 3056 * <p>This method should be used to indicate that a nested scrolling child has detected 3057 * suitable conditions for a fling. Generally this means that a touch scroll has ended with a 3058 * {@link VelocityTracker velocity} in the direction of scrolling that meets or exceeds 3059 * the {@link ViewConfiguration#getScaledMinimumFlingVelocity() minimum fling velocity} 3060 * along a scrollable axis.</p> 3061 * 3062 * <p>If a nested scrolling child view would normally fling but it is at the edge of 3063 * its own content, it can use this method to delegate the fling to its nested scrolling 3064 * parent instead. The parent may optionally consume the fling or observe a child fling.</p> 3065 * 3066 * @param velocityX Horizontal fling velocity in pixels per second 3067 * @param velocityY Vertical fling velocity in pixels per second 3068 * @param consumed true if the child consumed the fling, false otherwise 3069 * @return true if the nested scrolling parent consumed or otherwise reacted to the fling 3070 */ 3071 public static boolean dispatchNestedFling(View view, float velocityX, float velocityY, 3072 boolean consumed) { 3073 return IMPL.dispatchNestedFling(view, velocityX, velocityY, consumed); 3074 } 3075 3076 /** 3077 * Dispatch a fling to a nested scrolling parent before it is processed by this view. 3078 * 3079 * <p>Nested pre-fling events are to nested fling events what touch intercept is to touch 3080 * and what nested pre-scroll is to nested scroll. <code>dispatchNestedPreFling</code> 3081 * offsets an opportunity for the parent view in a nested fling to fully consume the fling 3082 * before the child view consumes it. If this method returns <code>true</code>, a nested 3083 * parent view consumed the fling and this view should not scroll as a result.</p> 3084 * 3085 * <p>For a better user experience, only one view in a nested scrolling chain should consume 3086 * the fling at a time. If a parent view consumed the fling this method will return false. 3087 * Custom view implementations should account for this in two ways:</p> 3088 * 3089 * <ul> 3090 * <li>If a custom view is paged and needs to settle to a fixed page-point, do not 3091 * call <code>dispatchNestedPreFling</code>; consume the fling and settle to a valid 3092 * position regardless.</li> 3093 * <li>If a nested parent does consume the fling, this view should not scroll at all, 3094 * even to settle back to a valid idle position.</li> 3095 * </ul> 3096 * 3097 * <p>Views should also not offer fling velocities to nested parent views along an axis 3098 * where scrolling is not currently supported; a {@link android.widget.ScrollView ScrollView} 3099 * should not offer a horizontal fling velocity to its parents since scrolling along that 3100 * axis is not permitted and carrying velocity along that motion does not make sense.</p> 3101 * 3102 * @param velocityX Horizontal fling velocity in pixels per second 3103 * @param velocityY Vertical fling velocity in pixels per second 3104 * @return true if a nested scrolling parent consumed the fling 3105 */ 3106 public static boolean dispatchNestedPreFling(View view, float velocityX, float velocityY) { 3107 return IMPL.dispatchNestedPreFling(view, velocityX, velocityY); 3108 } 3109 3110 /** 3111 * Returns whether the view hierarchy is currently undergoing a layout pass. This 3112 * information is useful to avoid situations such as calling {@link View#requestLayout()} 3113 * during a layout pass. 3114 * <p> 3115 * Compatibility: 3116 * <ul> 3117 * <li>API < 18: Always returns {@code false}</li> 3118 * </ul> 3119 * 3120 * @return whether the view hierarchy is currently undergoing a layout pass 3121 */ 3122 public static boolean isInLayout(View view) { 3123 return IMPL.isInLayout(view); 3124 } 3125 3126 /** 3127 * Returns true if {@code view} has been through at least one layout since it 3128 * was last attached to or detached from a window. 3129 */ 3130 public static boolean isLaidOut(View view) { 3131 return IMPL.isLaidOut(view); 3132 } 3133 3134 /** 3135 * Returns whether layout direction has been resolved. 3136 * <p> 3137 * Compatibility: 3138 * <ul> 3139 * <li>API < 19: Always returns {@code false}</li> 3140 * </ul> 3141 * 3142 * @return true if layout direction has been resolved. 3143 */ 3144 public static boolean isLayoutDirectionResolved(View view) { 3145 return IMPL.isLayoutDirectionResolved(view); 3146 } 3147 3148 /** 3149 * The visual z position of this view, in pixels. This is equivalent to the 3150 * {@link #setTranslationZ(View, float) translationZ} property plus the current 3151 * {@link #getElevation(View) elevation} property. 3152 * 3153 * @return The visual z position of this view, in pixels. 3154 */ 3155 public static float getZ(View view) { 3156 return IMPL.getZ(view); 3157 } 3158 3159 /** 3160 * Sets the visual z position of this view, in pixels. This is equivalent to setting the 3161 * {@link #setTranslationZ(View, float) translationZ} property to be the difference between 3162 * the x value passed in and the current {@link #getElevation(View) elevation} property. 3163 * <p> 3164 * Compatibility: 3165 * <ul> 3166 * <li>API < 21: No-op 3167 * </ul> 3168 * 3169 * @param z The visual z position of this view, in pixels. 3170 */ 3171 public static void setZ(View view, float z) { 3172 IMPL.setZ(view, z); 3173 } 3174 3175 /** 3176 * Offset this view's vertical location by the specified number of pixels. 3177 * 3178 * @param offset the number of pixels to offset the view by 3179 */ 3180 public static void offsetTopAndBottom(View view, int offset) { 3181 IMPL.offsetTopAndBottom(view, offset); 3182 } 3183 3184 /** 3185 * Offset this view's horizontal location by the specified amount of pixels. 3186 * 3187 * @param offset the number of pixels to offset the view by 3188 */ 3189 public static void offsetLeftAndRight(View view, int offset) { 3190 IMPL.offsetLeftAndRight(view, offset); 3191 } 3192 3193 /** 3194 * Sets a rectangular area on this view to which the view will be clipped 3195 * when it is drawn. Setting the value to null will remove the clip bounds 3196 * and the view will draw normally, using its full bounds. 3197 * 3198 * <p>Prior to API 18 this does nothing.</p> 3199 * 3200 * @param view The view to set clipBounds. 3201 * @param clipBounds The rectangular area, in the local coordinates of 3202 * this view, to which future drawing operations will be clipped. 3203 */ 3204 public static void setClipBounds(View view, Rect clipBounds) { 3205 IMPL.setClipBounds(view, clipBounds); 3206 } 3207 3208 /** 3209 * Returns a copy of the current {@link #setClipBounds(View, Rect)}. 3210 * 3211 * <p>Prior to API 18 this will return null.</p> 3212 * 3213 * @return A copy of the current clip bounds if clip bounds are set, 3214 * otherwise null. 3215 */ 3216 public static Rect getClipBounds(View view) { 3217 return IMPL.getClipBounds(view); 3218 } 3219 3220 /** 3221 * Returns true if the provided view is currently attached to a window. 3222 */ 3223 public static boolean isAttachedToWindow(View view) { 3224 return IMPL.isAttachedToWindow(view); 3225 } 3226 3227 /** 3228 * Returns whether the provided view has an attached {@link View.OnClickListener}. 3229 * 3230 * @return true if there is a listener, false if there is none. 3231 */ 3232 public static boolean hasOnClickListeners(View view) { 3233 return IMPL.hasOnClickListeners(view); 3234 } 3235 3236 /** 3237 * Sets the state of all scroll indicators. 3238 * <p> 3239 * See {@link #setScrollIndicators(View, int, int)} for usage information. 3240 * 3241 * @param indicators a bitmask of indicators that should be enabled, or 3242 * {@code 0} to disable all indicators 3243 * 3244 * @see #setScrollIndicators(View, int, int) 3245 * @see #getScrollIndicators(View) 3246 */ 3247 public static void setScrollIndicators(@NonNull View view, @ScrollIndicators int indicators) { 3248 IMPL.setScrollIndicators(view, indicators); 3249 } 3250 3251 /** 3252 * Sets the state of the scroll indicators specified by the mask. To change 3253 * all scroll indicators at once, see {@link #setScrollIndicators(View, int)}. 3254 * <p> 3255 * When a scroll indicator is enabled, it will be displayed if the view 3256 * can scroll in the direction of the indicator. 3257 * <p> 3258 * Multiple indicator types may be enabled or disabled by passing the 3259 * logical OR of the desired types. If multiple types are specified, they 3260 * will all be set to the same enabled state. 3261 * <p> 3262 * For example, to enable the top scroll indicatorExample: {@code setScrollIndicators} 3263 * 3264 * @param indicators the indicator direction, or the logical OR of multiple 3265 * indicator directions. One or more of: 3266 * <ul> 3267 * <li>{@link #SCROLL_INDICATOR_TOP}</li> 3268 * <li>{@link #SCROLL_INDICATOR_BOTTOM}</li> 3269 * <li>{@link #SCROLL_INDICATOR_LEFT}</li> 3270 * <li>{@link #SCROLL_INDICATOR_RIGHT}</li> 3271 * <li>{@link #SCROLL_INDICATOR_START}</li> 3272 * <li>{@link #SCROLL_INDICATOR_END}</li> 3273 * </ul> 3274 * 3275 * @see #setScrollIndicators(View, int) 3276 * @see #getScrollIndicators(View) 3277 */ 3278 public static void setScrollIndicators(@NonNull View view, @ScrollIndicators int indicators, 3279 @ScrollIndicators int mask) { 3280 IMPL.setScrollIndicators(view, indicators, mask); 3281 } 3282 3283 /** 3284 * Returns a bitmask representing the enabled scroll indicators. 3285 * <p> 3286 * For example, if the top and left scroll indicators are enabled and all 3287 * other indicators are disabled, the return value will be 3288 * {@code ViewCompat.SCROLL_INDICATOR_TOP | ViewCompat.SCROLL_INDICATOR_LEFT}. 3289 * <p> 3290 * To check whether the bottom scroll indicator is enabled, use the value 3291 * of {@code (ViewCompat.getScrollIndicators(view) & ViewCompat.SCROLL_INDICATOR_BOTTOM) != 0}. 3292 * 3293 * @return a bitmask representing the enabled scroll indicators 3294 */ 3295 public static int getScrollIndicators(@NonNull View view) { 3296 return IMPL.getScrollIndicators(view); 3297 } 3298 3299 /** 3300 * Set the pointer icon for the current view. 3301 * @param pointerIcon A PointerIconCompat instance which will be shown when the mouse hovers. 3302 */ 3303 public static void setPointerIcon(@NonNull View view, PointerIconCompat pointerIcon) { 3304 IMPL.setPointerIcon(view, pointerIcon); 3305 } 3306 3307 /** 3308 * Gets the logical display to which the view's window has been attached. 3309 * <p> 3310 * Compatibility: 3311 * <ul> 3312 * <li>API < 17: Returns the default display when the view is attached. Otherwise, null. 3313 * </ul> 3314 * 3315 * @return The logical display, or null if the view is not currently attached to a window. 3316 */ 3317 public static Display getDisplay(@NonNull View view) { 3318 return IMPL.getDisplay(view); 3319 } 3320 3321 /** 3322 * Sets the tooltip for the view. 3323 * 3324 * <p>Prior to API 26 this does nothing. Use TooltipCompat class from v7 appcompat library 3325 * for a compatible tooltip implementation.</p> 3326 * 3327 * @param tooltipText the tooltip text 3328 */ 3329 public static void setTooltipText(@NonNull View view, @Nullable CharSequence tooltipText) { 3330 IMPL.setTooltipText(view, tooltipText); 3331 } 3332 3333 /** 3334 * Start the drag and drop operation. 3335 */ 3336 public static boolean startDragAndDrop(View v, ClipData data, 3337 View.DragShadowBuilder shadowBuilder, Object localState, int flags) { 3338 return IMPL.startDragAndDrop(v, data, shadowBuilder, localState, flags); 3339 } 3340 3341 /** 3342 * Cancel the drag and drop operation. 3343 */ 3344 public static void cancelDragAndDrop(View v) { 3345 IMPL.cancelDragAndDrop(v); 3346 } 3347 3348 /** 3349 * Update the drag shadow while drag and drop is in progress. 3350 */ 3351 public static void updateDragShadow(View v, View.DragShadowBuilder shadowBuilder) { 3352 IMPL.updateDragShadow(v, shadowBuilder); 3353 } 3354 3355 protected ViewCompat() {} 3356} 3357