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