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