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