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