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