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