ViewCompat.java revision d72e9db013c885dd699ad749b69409ffb6894838
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,
1814                    pointerIconCompat != null ? pointerIconCompat.getPointerIcon() : null);
1815        }
1816    }
1817
1818    static final ViewCompatImpl IMPL;
1819    static {
1820        final int version = android.os.Build.VERSION.SDK_INT;
1821        if (BuildCompat.isAtLeastN()) {
1822            IMPL = new Api24ViewCompatImpl();
1823        } else if (version >= 23) {
1824            IMPL = new MarshmallowViewCompatImpl();
1825        } else if (version >= 21) {
1826            IMPL = new LollipopViewCompatImpl();
1827        } else if (version >= 19) {
1828            IMPL = new KitKatViewCompatImpl();
1829        } else if (version >= 18) {
1830            IMPL = new JbMr2ViewCompatImpl();
1831        } else if (version >= 17) {
1832            IMPL = new JbMr1ViewCompatImpl();
1833        } else if (version >= 16) {
1834            IMPL = new JBViewCompatImpl();
1835        } else if (version >= 15) {
1836            IMPL = new ICSMr1ViewCompatImpl();
1837        } else if (version >= 14) {
1838            IMPL = new ICSViewCompatImpl();
1839        } else if (version >= 11) {
1840            IMPL = new HCViewCompatImpl();
1841        } else {
1842            IMPL = new BaseViewCompatImpl();
1843        }
1844    }
1845
1846    /**
1847     * Check if this view can be scrolled horizontally in a certain direction.
1848     *
1849     * @param v The View against which to invoke the method.
1850     * @param direction Negative to check scrolling left, positive to check scrolling right.
1851     * @return true if this view can be scrolled in the specified direction, false otherwise.
1852     */
1853    public static boolean canScrollHorizontally(View v, int direction) {
1854        return IMPL.canScrollHorizontally(v, direction);
1855    }
1856
1857    /**
1858     * Check if this view can be scrolled vertically in a certain direction.
1859     *
1860     * @param v The View against which to invoke the method.
1861     * @param direction Negative to check scrolling up, positive to check scrolling down.
1862     * @return true if this view can be scrolled in the specified direction, false otherwise.
1863     */
1864    public static boolean canScrollVertically(View v, int direction) {
1865        return IMPL.canScrollVertically(v, direction);
1866    }
1867
1868    /**
1869     * Returns the over-scroll mode for this view. The result will be
1870     * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
1871     * (allow over-scrolling only if the view content is larger than the container),
1872     * or {@link #OVER_SCROLL_NEVER}.
1873     *
1874     * @param v The View against which to invoke the method.
1875     * @return This view's over-scroll mode.
1876     * @deprecated Call {@link View#getOverScrollMode()} directly. This method will be
1877     * removed in a future release.
1878     */
1879    @Deprecated
1880    @OverScroll
1881    public static int getOverScrollMode(View v) {
1882        //noinspection ResourceType
1883        return v.getOverScrollMode();
1884    }
1885
1886    /**
1887     * Set the over-scroll mode for this view. Valid over-scroll modes are
1888     * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
1889     * (allow over-scrolling only if the view content is larger than the container),
1890     * or {@link #OVER_SCROLL_NEVER}.
1891     *
1892     * Setting the over-scroll mode of a view will have an effect only if the
1893     * view is capable of scrolling.
1894     *
1895     * @param v The View against which to invoke the method.
1896     * @param overScrollMode The new over-scroll mode for this view.
1897     * @deprecated Call {@link View#setOverScrollMode(int)} directly. This method will be
1898     * removed in a future release.
1899     */
1900    @Deprecated
1901    public static void setOverScrollMode(View v, @OverScroll int overScrollMode) {
1902        v.setOverScrollMode(overScrollMode);
1903    }
1904
1905    /**
1906     * Called from {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
1907     * giving a chance to this View to populate the accessibility event with its
1908     * text content. While this method is free to modify event
1909     * attributes other than text content, doing so should normally be performed in
1910     * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)}.
1911     * <p>
1912     * Example: Adding formatted date string to an accessibility event in addition
1913     *          to the text added by the super implementation:
1914     * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
1915     *     super.onPopulateAccessibilityEvent(event);
1916     *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
1917     *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
1918     *         mCurrentDate.getTimeInMillis(), flags);
1919     *     event.getText().add(selectedDateUtterance);
1920     * }</pre>
1921     * <p>
1922     * If an {@link AccessibilityDelegateCompat} has been specified via calling
1923     * {@link ViewCompat#setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
1924     * {@link AccessibilityDelegateCompat#onPopulateAccessibilityEvent(View, AccessibilityEvent)}
1925     * is responsible for handling this call.
1926     * </p>
1927     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
1928     * information to the event, in case the default implementation has basic information to add.
1929     * </p>
1930     *
1931     * @param v The View against which to invoke the method.
1932     * @param event The accessibility event which to populate.
1933     *
1934     * @see View#sendAccessibilityEvent(int)
1935     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
1936     */
1937    public static void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
1938        IMPL.onPopulateAccessibilityEvent(v, event);
1939    }
1940
1941    /**
1942     * Initializes an {@link AccessibilityEvent} with information about
1943     * this View which is the event source. In other words, the source of
1944     * an accessibility event is the view whose state change triggered firing
1945     * the event.
1946     * <p>
1947     * Example: Setting the password property of an event in addition
1948     *          to properties set by the super implementation:
1949     * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
1950     *     super.onInitializeAccessibilityEvent(event);
1951     *     event.setPassword(true);
1952     * }</pre>
1953     * <p>
1954     * If an {@link AccessibilityDelegateCompat} has been specified via calling
1955     * {@link ViewCompat#setAccessibilityDelegate(View, AccessibilityDelegateCompat)}, its
1956     * {@link AccessibilityDelegateCompat#onInitializeAccessibilityEvent(View, AccessibilityEvent)}
1957     * is responsible for handling this call.
1958     *
1959     * @param v The View against which to invoke the method.
1960     * @param event The event to initialize.
1961     *
1962     * @see View#sendAccessibilityEvent(int)
1963     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
1964     */
1965    public static void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
1966        IMPL.onInitializeAccessibilityEvent(v, event);
1967    }
1968
1969    /**
1970     * Initializes an {@link AccessibilityNodeInfoCompat} with information
1971     * about this view. The base implementation sets:
1972     * <ul>
1973     * <li>{@link AccessibilityNodeInfoCompat#setParent(View)},</li>
1974     * <li>{@link AccessibilityNodeInfoCompat#setBoundsInParent(Rect)},</li>
1975     * <li>{@link AccessibilityNodeInfoCompat#setBoundsInScreen(Rect)},</li>
1976     * <li>{@link AccessibilityNodeInfoCompat#setPackageName(CharSequence)},</li>
1977     * <li>{@link AccessibilityNodeInfoCompat#setClassName(CharSequence)},</li>
1978     * <li>{@link AccessibilityNodeInfoCompat#setContentDescription(CharSequence)},</li>
1979     * <li>{@link AccessibilityNodeInfoCompat#setEnabled(boolean)},</li>
1980     * <li>{@link AccessibilityNodeInfoCompat#setClickable(boolean)},</li>
1981     * <li>{@link AccessibilityNodeInfoCompat#setFocusable(boolean)},</li>
1982     * <li>{@link AccessibilityNodeInfoCompat#setFocused(boolean)},</li>
1983     * <li>{@link AccessibilityNodeInfoCompat#setLongClickable(boolean)},</li>
1984     * <li>{@link AccessibilityNodeInfoCompat#setSelected(boolean)},</li>
1985     * </ul>
1986     * <p>
1987     * If an {@link AccessibilityDelegateCompat} has been specified via calling
1988     * {@link ViewCompat#setAccessibilityDelegate(View, AccessibilityDelegateCompat)}, its
1989     * {@link AccessibilityDelegateCompat#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)}
1990     * method is responsible for handling this call.
1991     *
1992     * @param v The View against which to invoke the method.
1993     * @param info The instance to initialize.
1994     */
1995    public static void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
1996        IMPL.onInitializeAccessibilityNodeInfo(v, info);
1997    }
1998
1999    /**
2000     * Sets a delegate for implementing accessibility support via composition
2001     * (as opposed to inheritance). For more details, see
2002     * {@link AccessibilityDelegateCompat}.
2003     * <p>
2004     * On platform versions prior to API 14, this method is a no-op.
2005     * <p>
2006     * <strong>Note:</strong> On platform versions prior to
2007     * {@link android.os.Build.VERSION_CODES#M API 23}, delegate methods on
2008     * views in the {@code android.widget.*} package are called <i>before</i>
2009     * host methods. This prevents certain properties such as class name from
2010     * being modified by overriding
2011     * {@link AccessibilityDelegateCompat#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)},
2012     * as any changes will be overwritten by the host class.
2013     * <p>
2014     * Starting in {@link android.os.Build.VERSION_CODES#M API 23}, delegate
2015     * methods are called <i>after</i> host methods, which all properties to be
2016     * modified without being overwritten by the host class.
2017     *
2018     * @param delegate the object to which accessibility method calls should be
2019     *                 delegated
2020     * @see AccessibilityDelegateCompat
2021     */
2022    public static void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
2023        IMPL.setAccessibilityDelegate(v, delegate);
2024    }
2025
2026    /**
2027     * Checks whether provided View has an accessibility delegate attached to it.
2028     *
2029     * @param v The View instance to check
2030     * @return True if the View has an accessibility delegate
2031     */
2032    public static boolean hasAccessibilityDelegate(View v) {
2033        return IMPL.hasAccessibilityDelegate(v);
2034    }
2035
2036    /**
2037     * Indicates whether the view is currently tracking transient state that the
2038     * app should not need to concern itself with saving and restoring, but that
2039     * the framework should take special note to preserve when possible.
2040     *
2041     * @param view View to check for transient state
2042     * @return true if the view has transient state
2043     */
2044    public static boolean hasTransientState(View view) {
2045        return IMPL.hasTransientState(view);
2046    }
2047
2048    /**
2049     * Set whether this view is currently tracking transient state that the
2050     * framework should attempt to preserve when possible.
2051     *
2052     * @param view View tracking transient state
2053     * @param hasTransientState true if this view has transient state
2054     */
2055    public static void setHasTransientState(View view, boolean hasTransientState) {
2056        IMPL.setHasTransientState(view, hasTransientState);
2057    }
2058
2059    /**
2060     * <p>Cause an invalidate to happen on the next animation time step, typically the
2061     * next display frame.</p>
2062     *
2063     * <p>This method can be invoked from outside of the UI thread
2064     * only when this View is attached to a window.</p>
2065     *
2066     * @param view View to invalidate
2067     */
2068    public static void postInvalidateOnAnimation(View view) {
2069        IMPL.postInvalidateOnAnimation(view);
2070    }
2071
2072    /**
2073     * <p>Cause an invalidate of the specified area to happen on the next animation
2074     * time step, typically the next display frame.</p>
2075     *
2076     * <p>This method can be invoked from outside of the UI thread
2077     * only when this View is attached to a window.</p>
2078     *
2079     * @param view View to invalidate
2080     * @param left The left coordinate of the rectangle to invalidate.
2081     * @param top The top coordinate of the rectangle to invalidate.
2082     * @param right The right coordinate of the rectangle to invalidate.
2083     * @param bottom The bottom coordinate of the rectangle to invalidate.
2084     */
2085    public static void postInvalidateOnAnimation(View view, int left, int top,
2086            int right, int bottom) {
2087        IMPL.postInvalidateOnAnimation(view, left, top, right, bottom);
2088    }
2089
2090    /**
2091     * <p>Causes the Runnable to execute on the next animation time step.
2092     * The runnable will be run on the user interface thread.</p>
2093     *
2094     * <p>This method can be invoked from outside of the UI thread
2095     * only when this View is attached to a window.</p>
2096     *
2097     * @param view View to post this Runnable to
2098     * @param action The Runnable that will be executed.
2099     */
2100    public static void postOnAnimation(View view, Runnable action) {
2101        IMPL.postOnAnimation(view, action);
2102    }
2103
2104    /**
2105     * <p>Causes the Runnable to execute on the next animation time step,
2106     * after the specified amount of time elapses.
2107     * The runnable will be run on the user interface thread.</p>
2108     *
2109     * <p>This method can be invoked from outside of the UI thread
2110     * only when this View is attached to a window.</p>
2111     *
2112     * @param view The view to post this Runnable to
2113     * @param action The Runnable that will be executed.
2114     * @param delayMillis The delay (in milliseconds) until the Runnable
2115     *        will be executed.
2116     */
2117    public static void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
2118        IMPL.postOnAnimationDelayed(view, action, delayMillis);
2119    }
2120
2121    /**
2122     * Gets the mode for determining whether this View is important for accessibility
2123     * which is if it fires accessibility events and if it is reported to
2124     * accessibility services that query the screen.
2125     *
2126     * @param view The view whose property to get.
2127     * @return The mode for determining whether a View is important for accessibility.
2128     *
2129     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
2130     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
2131     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
2132     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
2133     */
2134    @ImportantForAccessibility
2135    public static int getImportantForAccessibility(View view) {
2136        //noinspection ResourceType
2137        return IMPL.getImportantForAccessibility(view);
2138    }
2139
2140    /**
2141     * Sets how to determine whether this view is important for accessibility
2142     * which is if it fires accessibility events and if it is reported to
2143     * accessibility services that query the screen.
2144     * <p>
2145     * <em>Note:</em> If the current platform version does not support the
2146     *  {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} mode, then
2147     *  {@link #IMPORTANT_FOR_ACCESSIBILITY_NO} will be used as it is the
2148     *  closest terms of semantics.
2149     * </p>
2150     *
2151     * @param view The view whose property to set.
2152     * @param mode How to determine whether this view is important for accessibility.
2153     *
2154     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
2155     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
2156     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
2157     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
2158     */
2159    public static void setImportantForAccessibility(View view,
2160            @ImportantForAccessibility int mode) {
2161        IMPL.setImportantForAccessibility(view, mode);
2162    }
2163
2164    /**
2165     * Computes whether this view should be exposed for accessibility. In
2166     * general, views that are interactive or provide information are exposed
2167     * while views that serve only as containers are hidden.
2168     * <p>
2169     * If an ancestor of this view has importance
2170     * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, this method
2171     * returns <code>false</code>.
2172     * <p>
2173     * Otherwise, the value is computed according to the view's
2174     * {@link #getImportantForAccessibility(View)} value:
2175     * <ol>
2176     * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_NO} or
2177     * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, return <code>false
2178     * </code>
2179     * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_YES}, return <code>true</code>
2180     * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_AUTO}, return <code>true</code> if
2181     * view satisfies any of the following:
2182     * <ul>
2183     * <li>Is actionable, e.g. {@link View#isClickable()},
2184     * {@link View#isLongClickable()}, or {@link View#isFocusable()}
2185     * <li>Has an {@link AccessibilityDelegateCompat}
2186     * <li>Has an interaction listener, e.g. {@link View.OnTouchListener},
2187     * {@link View.OnKeyListener}, etc.
2188     * <li>Is an accessibility live region, e.g.
2189     * {@link #getAccessibilityLiveRegion(View)} is not
2190     * {@link #ACCESSIBILITY_LIVE_REGION_NONE}.
2191     * </ul>
2192     * </ol>
2193     * <p>
2194     * <em>Note:</em> Prior to API 21, this method will always return {@code true}.
2195     *
2196     * @return Whether the view is exposed for accessibility.
2197     * @see #setImportantForAccessibility(View, int)
2198     * @see #getImportantForAccessibility(View)
2199     */
2200    public static boolean isImportantForAccessibility(View view) {
2201        return IMPL.isImportantForAccessibility(view);
2202    }
2203
2204    /**
2205     * Performs the specified accessibility action on the view. For
2206     * possible accessibility actions look at {@link AccessibilityNodeInfoCompat}.
2207     * <p>
2208     * If an {@link AccessibilityDelegateCompat} has been specified via calling
2209     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
2210     * {@link AccessibilityDelegateCompat#performAccessibilityAction(View, int, Bundle)}
2211     * is responsible for handling this call.
2212     * </p>
2213     *
2214     * @param action The action to perform.
2215     * @param arguments Optional action arguments.
2216     * @return Whether the action was performed.
2217     */
2218    public static boolean performAccessibilityAction(View view, int action, Bundle arguments) {
2219        return IMPL.performAccessibilityAction(view, action, arguments);
2220    }
2221
2222    /**
2223     * Gets the provider for managing a virtual view hierarchy rooted at this View
2224     * and reported to {@link android.accessibilityservice.AccessibilityService}s
2225     * that explore the window content.
2226     * <p>
2227     * If this method returns an instance, this instance is responsible for managing
2228     * {@link AccessibilityNodeInfoCompat}s describing the virtual sub-tree rooted at
2229     * this View including the one representing the View itself. Similarly the returned
2230     * instance is responsible for performing accessibility actions on any virtual
2231     * view or the root view itself.
2232     * </p>
2233     * <p>
2234     * If an {@link AccessibilityDelegateCompat} has been specified via calling
2235     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
2236     * {@link AccessibilityDelegateCompat#getAccessibilityNodeProvider(View)}
2237     * is responsible for handling this call.
2238     * </p>
2239     *
2240     * @param view The view whose property to get.
2241     * @return The provider.
2242     *
2243     * @see AccessibilityNodeProviderCompat
2244     */
2245    public static AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
2246        return IMPL.getAccessibilityNodeProvider(view);
2247    }
2248
2249    /**
2250     * The opacity of the view. This is a value from 0 to 1, where 0 means the view is
2251     * completely transparent and 1 means the view is completely opaque.
2252     *
2253     * <p>By default this is 1.0f. Prior to API 11, the returned value is always 1.0f.
2254     * @return The opacity of the view.
2255     */
2256    public static float getAlpha(View view) {
2257        return IMPL.getAlpha(view);
2258    }
2259
2260    /**
2261     * <p>Specifies the type of layer backing this view. The layer can be
2262     * {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or
2263     * {@link #LAYER_TYPE_HARDWARE hardware}.</p>
2264     *
2265     * <p>A layer is associated with an optional {@link android.graphics.Paint}
2266     * instance that controls how the layer is composed on screen. The following
2267     * properties of the paint are taken into account when composing the layer:</p>
2268     * <ul>
2269     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
2270     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
2271     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
2272     * </ul>
2273     *
2274     * <p>If this view has an alpha value set to < 1.0 by calling
2275     * setAlpha(float), the alpha value of the layer's paint is replaced by
2276     * this view's alpha value. Calling setAlpha(float) is therefore
2277     * equivalent to setting a hardware layer on this view and providing a paint with
2278     * the desired alpha value.<p>
2279     *
2280     * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled},
2281     * {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware}
2282     * for more information on when and how to use layers.</p>
2283     *
2284     * @param view View to set the layer type for
2285     * @param layerType The type of layer to use with this view, must be one of
2286     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
2287     *        {@link #LAYER_TYPE_HARDWARE}
2288     * @param paint The paint used to compose the layer. This argument is optional
2289     *        and can be null. It is ignored when the layer type is
2290     *        {@link #LAYER_TYPE_NONE}
2291     */
2292    public static void setLayerType(View view, @LayerType int layerType, Paint paint) {
2293        IMPL.setLayerType(view, layerType, paint);
2294    }
2295
2296    /**
2297     * Indicates what type of layer is currently associated with this view. By default
2298     * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
2299     * Refer to the documentation of
2300     * {@link #setLayerType(android.view.View, int, android.graphics.Paint)}
2301     * for more information on the different types of layers.
2302     *
2303     * @param view The view to fetch the layer type from
2304     * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
2305     *         {@link #LAYER_TYPE_HARDWARE}
2306     *
2307     * @see #setLayerType(android.view.View, int, android.graphics.Paint)
2308     * @see #LAYER_TYPE_NONE
2309     * @see #LAYER_TYPE_SOFTWARE
2310     * @see #LAYER_TYPE_HARDWARE
2311     */
2312    @LayerType
2313    public static int getLayerType(View view) {
2314        //noinspection ResourceType
2315        return IMPL.getLayerType(view);
2316    }
2317
2318    /**
2319     * Gets the id of a view for which a given view serves as a label for
2320     * accessibility purposes.
2321     *
2322     * @param view The view on which to invoke the corresponding method.
2323     * @return The labeled view id.
2324     */
2325    public static int getLabelFor(View view) {
2326        return IMPL.getLabelFor(view);
2327    }
2328
2329    /**
2330     * Sets the id of a view for which a given view serves as a label for
2331     * accessibility purposes.
2332     *
2333     * @param view The view on which to invoke the corresponding method.
2334     * @param labeledId The labeled view id.
2335     */
2336    public static void setLabelFor(View view, @IdRes int labeledId) {
2337        IMPL.setLabelFor(view, labeledId);
2338    }
2339
2340    /**
2341     * Updates the {@link Paint} object used with the current layer (used only if the current
2342     * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
2343     * provided to {@link #setLayerType(android.view.View, int, android.graphics.Paint)}
2344     * will be used the next time the View is redrawn, but
2345     * {@link #setLayerPaint(android.view.View, android.graphics.Paint)}
2346     * must be called to ensure that the view gets redrawn immediately.
2347     *
2348     * <p>A layer is associated with an optional {@link android.graphics.Paint}
2349     * instance that controls how the layer is composed on screen. The following
2350     * properties of the paint are taken into account when composing the layer:</p>
2351     * <ul>
2352     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
2353     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
2354     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
2355     * </ul>
2356     *
2357     * <p>If this view has an alpha value set to < 1.0 by calling
2358     * View#setAlpha(float), the alpha value of the layer's paint is replaced by
2359     * this view's alpha value. Calling View#setAlpha(float) is therefore
2360     * equivalent to setting a hardware layer on this view and providing a paint with
2361     * the desired alpha value.</p>
2362     *
2363     * @param view View to set a layer paint for
2364     * @param paint The paint used to compose the layer. This argument is optional
2365     *        and can be null. It is ignored when the layer type is
2366     *        {@link #LAYER_TYPE_NONE}
2367     *
2368     * @see #setLayerType(View, int, android.graphics.Paint)
2369     */
2370    public static void setLayerPaint(View view, Paint paint) {
2371        IMPL.setLayerPaint(view, paint);
2372    }
2373
2374    /**
2375     * Returns the resolved layout direction for this view.
2376     *
2377     * @param view View to get layout direction for
2378     * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
2379     * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
2380     *
2381     * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version
2382     * is lower than Jellybean MR1 (API 17)
2383     */
2384    @ResolvedLayoutDirectionMode
2385    public static int getLayoutDirection(View view) {
2386        //noinspection ResourceType
2387        return IMPL.getLayoutDirection(view);
2388    }
2389
2390    /**
2391     * Set the layout direction for this view. This will propagate a reset of layout direction
2392     * resolution to the view's children and resolve layout direction for this view.
2393     *
2394     * @param view View to set layout direction for
2395     * @param layoutDirection the layout direction to set. Should be one of:
2396     *
2397     * {@link #LAYOUT_DIRECTION_LTR},
2398     * {@link #LAYOUT_DIRECTION_RTL},
2399     * {@link #LAYOUT_DIRECTION_INHERIT},
2400     * {@link #LAYOUT_DIRECTION_LOCALE}.
2401     *
2402     * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution
2403     * proceeds up the parent chain of the view to get the value. If there is no parent, then it
2404     * will return the default {@link #LAYOUT_DIRECTION_LTR}.
2405     */
2406    public static void setLayoutDirection(View view, @LayoutDirectionMode int layoutDirection) {
2407        IMPL.setLayoutDirection(view, layoutDirection);
2408    }
2409
2410    /**
2411     * Gets the parent for accessibility purposes. Note that the parent for
2412     * accessibility is not necessary the immediate parent. It is the first
2413     * predecessor that is important for accessibility.
2414     *
2415     * @param view View to retrieve parent for
2416     * @return The parent for use in accessibility inspection
2417     */
2418    public static ViewParent getParentForAccessibility(View view) {
2419        return IMPL.getParentForAccessibility(view);
2420    }
2421
2422    /**
2423     * Indicates whether this View is opaque. An opaque View guarantees that it will
2424     * draw all the pixels overlapping its bounds using a fully opaque color.
2425     *
2426     * @return True if this View is guaranteed to be fully opaque, false otherwise.
2427     * @deprecated Use {@link View#isOpaque()} directly. This method will be
2428     * removed in a future release.
2429     */
2430    @Deprecated
2431    public static boolean isOpaque(View view) {
2432        return view.isOpaque();
2433    }
2434
2435    /**
2436     * Utility to reconcile a desired size and state, with constraints imposed
2437     * by a MeasureSpec.  Will take the desired size, unless a different size
2438     * is imposed by the constraints.  The returned value is a compound integer,
2439     * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
2440     * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting
2441     * size is smaller than the size the view wants to be.
2442     *
2443     * @param size How big the view wants to be
2444     * @param measureSpec Constraints imposed by the parent
2445     * @return Size information bit mask as defined by
2446     * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
2447     */
2448    public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
2449        return IMPL.resolveSizeAndState(size, measureSpec, childMeasuredState);
2450    }
2451
2452    /**
2453     * Return the full width measurement information for this view as computed
2454     * by the most recent call to {@link android.view.View#measure(int, int)}.
2455     * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and
2456     * {@link #MEASURED_STATE_TOO_SMALL}.
2457     * This should be used during measurement and layout calculations only. Use
2458     * {@link android.view.View#getWidth()} to see how wide a view is after layout.
2459     *
2460     * @return The measured width of this view as a bit mask.
2461     */
2462    public static int getMeasuredWidthAndState(View view) {
2463        return IMPL.getMeasuredWidthAndState(view);
2464    }
2465
2466    /**
2467     * Return the full height measurement information for this view as computed
2468     * by the most recent call to {@link android.view.View#measure(int, int)}.
2469     * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and
2470     * {@link #MEASURED_STATE_TOO_SMALL}.
2471     * This should be used during measurement and layout calculations only. Use
2472     * {@link android.view.View#getHeight()} to see how wide a view is after layout.
2473     *
2474     * @return The measured width of this view as a bit mask.
2475     */
2476    public static int getMeasuredHeightAndState(View view) {
2477        return IMPL.getMeasuredHeightAndState(view);
2478    }
2479
2480    /**
2481     * Return only the state bits of {@link #getMeasuredWidthAndState}
2482     * and {@link #getMeasuredHeightAndState}, combined into one integer.
2483     * The width component is in the regular bits {@link #MEASURED_STATE_MASK}
2484     * and the height component is at the shifted bits
2485     * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}.
2486     */
2487    public static int getMeasuredState(View view) {
2488        return IMPL.getMeasuredState(view);
2489    }
2490
2491    /**
2492     * Merge two states as returned by {@link #getMeasuredState(View)}.
2493     * @param curState The current state as returned from a view or the result
2494     * of combining multiple views.
2495     * @param newState The new view state to combine.
2496     * @return Returns a new integer reflecting the combination of the two
2497     * states.
2498     */
2499    public static int combineMeasuredStates(int curState, int newState) {
2500        return IMPL.combineMeasuredStates(curState, newState);
2501    }
2502
2503    /**
2504     * Gets the live region mode for the specified View.
2505     *
2506     * @param view The view from which to obtain the live region mode
2507     * @return The live region mode for the view.
2508     *
2509     * @see ViewCompat#setAccessibilityLiveRegion(View, int)
2510     */
2511    @AccessibilityLiveRegion
2512    public static int getAccessibilityLiveRegion(View view) {
2513        //noinspection ResourceType
2514        return IMPL.getAccessibilityLiveRegion(view);
2515    }
2516
2517    /**
2518     * Sets the live region mode for the specified view. This indicates to
2519     * accessibility services whether they should automatically notify the user
2520     * about changes to the view's content description or text, or to the
2521     * content descriptions or text of the view's children (where applicable).
2522     * <p>
2523     * For example, in a login screen with a TextView that displays an "incorrect
2524     * password" notification, that view should be marked as a live region with
2525     * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
2526     * <p>
2527     * To disable change notifications for this view, use
2528     * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
2529     * mode for most views.
2530     * <p>
2531     * To indicate that the user should be notified of changes, use
2532     * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
2533     * <p>
2534     * If the view's changes should interrupt ongoing speech and notify the user
2535     * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}.
2536     *
2537     * @param view The view on which to set the live region mode
2538     * @param mode The live region mode for this view, one of:
2539     *        <ul>
2540     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE}
2541     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE}
2542     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
2543     *        </ul>
2544     */
2545    public static void setAccessibilityLiveRegion(View view, @AccessibilityLiveRegion int mode) {
2546        IMPL.setAccessibilityLiveRegion(view, mode);
2547    }
2548
2549    /**
2550     * Returns the start padding of the specified view depending on its resolved layout direction.
2551     * If there are inset and enabled scrollbars, this value may include the space
2552     * required to display the scrollbars as well.
2553     *
2554     * @param view The view to get padding for
2555     * @return the start padding in pixels
2556     */
2557    public static int getPaddingStart(View view) {
2558        return IMPL.getPaddingStart(view);
2559    }
2560
2561    /**
2562     * Returns the end padding of the specified view depending on its resolved layout direction.
2563     * If there are inset and enabled scrollbars, this value may include the space
2564     * required to display the scrollbars as well.
2565     *
2566     * @param view The view to get padding for
2567     * @return the end padding in pixels
2568     */
2569    public static int getPaddingEnd(View view) {
2570        return IMPL.getPaddingEnd(view);
2571    }
2572
2573    /**
2574     * Sets the relative padding. The view may add on the space required to display
2575     * the scrollbars, depending on the style and visibility of the scrollbars.
2576     * So the values returned from {@link #getPaddingStart}, {@link View#getPaddingTop},
2577     * {@link #getPaddingEnd} and {@link View#getPaddingBottom} may be different
2578     * from the values set in this call.
2579     *
2580     * @param view The view on which to set relative padding
2581     * @param start the start padding in pixels
2582     * @param top the top padding in pixels
2583     * @param end the end padding in pixels
2584     * @param bottom the bottom padding in pixels
2585     */
2586    public static void setPaddingRelative(View view, int start, int top, int end, int bottom) {
2587        IMPL.setPaddingRelative(view, start, top, end, bottom);
2588    }
2589
2590    /**
2591     * Notify a view that it is being temporarily detached.
2592     */
2593    public static void dispatchStartTemporaryDetach(View view) {
2594        IMPL.dispatchStartTemporaryDetach(view);
2595    }
2596
2597    /**
2598     * Notify a view that its temporary detach has ended; the view is now reattached.
2599     */
2600    public static void dispatchFinishTemporaryDetach(View view) {
2601        IMPL.dispatchFinishTemporaryDetach(view);
2602    }
2603
2604    /**
2605     * The horizontal location of this view relative to its {@link View#getLeft() left} position.
2606     * This position is post-layout, in addition to wherever the object's
2607     * layout placed it.
2608     *
2609     * <p>Prior to API 11 this will return 0.</p>
2610     *
2611     * @return The horizontal position of this view relative to its left position, in pixels.
2612     */
2613    public static float getTranslationX(View view) {
2614        return IMPL.getTranslationX(view);
2615    }
2616
2617    /**
2618     * The vertical location of this view relative to its {@link View#getTop() top} position.
2619     * This position is post-layout, in addition to wherever the object's
2620     * layout placed it.
2621     *
2622     * <p>Prior to API 11 this will return 0.</p>
2623     *
2624     * @return The vertical position of this view relative to its top position, in pixels.
2625     */
2626    public static float getTranslationY(View view) {
2627        return IMPL.getTranslationY(view);
2628    }
2629
2630    /**
2631     * The transform matrix of this view, which is calculated based on the current
2632     * rotation, scale, and pivot properties.
2633     * <p>
2634     * Prior to 11, this method will return {@code null}.
2635     *
2636     * @param view The view whose Matrix will be returned
2637     * @return The current transform matrix for the view
2638     *
2639     * @see #getRotation(View)
2640     * @see #getScaleX(View)
2641     * @see #getScaleY(View)
2642     * @see #getPivotX(View)
2643     * @see #getPivotY(View)
2644     */
2645    @Nullable
2646    public static Matrix getMatrix(View view) {
2647        return IMPL.getMatrix(view);
2648    }
2649
2650    /**
2651     * Returns the minimum width of the view.
2652     *
2653     * <p>Prior to API 16 this will return 0.</p>
2654     *
2655     * @return the minimum width the view will try to be.
2656     */
2657    public static int getMinimumWidth(View view) {
2658        return IMPL.getMinimumWidth(view);
2659    }
2660
2661    /**
2662     * Returns the minimum height of the view.
2663     *
2664     * <p>Prior to API 16 this will return 0.</p>
2665     *
2666     * @return the minimum height the view will try to be.
2667     */
2668    public static int getMinimumHeight(View view) {
2669        return IMPL.getMinimumHeight(view);
2670    }
2671
2672    /**
2673     * This method returns a ViewPropertyAnimator object, which can be used to animate
2674     * specific properties on this View.
2675     *
2676     * <p>Prior to API 14, this method will do nothing.</p>
2677     *
2678     * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
2679     */
2680    public static ViewPropertyAnimatorCompat animate(View view) {
2681        return IMPL.animate(view);
2682    }
2683
2684    /**
2685     * Sets the horizontal location of this view relative to its left position.
2686     * This effectively positions the object post-layout, in addition to wherever the object's
2687     * layout placed it.
2688     *
2689     * <p>Prior to API 11 this will have no effect.</p>
2690     *
2691     * @param value The horizontal position of this view relative to its left position,
2692     * in pixels.
2693     */
2694    public static void setTranslationX(View view, float value) {
2695        IMPL.setTranslationX(view, value);
2696    }
2697
2698    /**
2699     * Sets the vertical location of this view relative to its top position.
2700     * This effectively positions the object post-layout, in addition to wherever the object's
2701     * layout placed it.
2702     *
2703     * <p>Prior to API 11 this will have no effect.</p>
2704     *
2705     * @param value The vertical position of this view relative to its top position,
2706     * in pixels.
2707     *
2708     * @attr name android:translationY
2709     */
2710    public static void setTranslationY(View view, float value) {
2711        IMPL.setTranslationY(view, value);
2712    }
2713
2714    /**
2715     * <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
2716     * completely transparent and 1 means the view is completely opaque.</p>
2717     *
2718     * <p> Note that setting alpha to a translucent value (0 < alpha < 1) can have significant
2719     * performance implications, especially for large views. It is best to use the alpha property
2720     * sparingly and transiently, as in the case of fading animations.</p>
2721     *
2722     * <p>Prior to API 11 this will have no effect.</p>
2723     *
2724     * @param value The opacity of the view.
2725     */
2726    public static void setAlpha(View view, @FloatRange(from=0.0, to=1.0) float value) {
2727        IMPL.setAlpha(view, value);
2728    }
2729
2730    /**
2731     * Sets the visual x position of this view, in pixels. This is equivalent to setting the
2732     * {@link #setTranslationX(View, float) translationX} property to be the difference between
2733     * the x value passed in and the current left property of the view as determined
2734     * by the layout bounds.
2735     *
2736     * <p>Prior to API 11 this will have no effect.</p>
2737     *
2738     * @param value The visual x position of this view, in pixels.
2739     */
2740    public static void setX(View view, float value) {
2741        IMPL.setX(view, value);
2742    }
2743
2744    /**
2745     * Sets the visual y position of this view, in pixels. This is equivalent to setting the
2746     * {@link #setTranslationY(View, float) translationY} property to be the difference between
2747     * the y value passed in and the current top property of the view as determined by the
2748     * layout bounds.
2749     *
2750     * <p>Prior to API 11 this will have no effect.</p>
2751     *
2752     * @param value The visual y position of this view, in pixels.
2753     */
2754    public static void setY(View view, float value) {
2755        IMPL.setY(view, value);
2756    }
2757
2758    /**
2759     * Sets the degrees that the view is rotated around the pivot point. Increasing values
2760     * result in clockwise rotation.
2761     *
2762     * <p>Prior to API 11 this will have no effect.</p>
2763     *
2764     * @param value The degrees of rotation.
2765     */
2766    public static void setRotation(View view, float value) {
2767        IMPL.setRotation(view, value);
2768    }
2769
2770    /**
2771     * Sets the degrees that the view is rotated around the horizontal axis through the pivot point.
2772     * Increasing values result in clockwise rotation from the viewpoint of looking down the
2773     * x axis.
2774     *
2775     * <p>Prior to API 11 this will have no effect.</p>
2776     *
2777     * @param value The degrees of X rotation.
2778     */
2779    public static void setRotationX(View view, float value) {
2780        IMPL.setRotationX(view, value);
2781    }
2782
2783    /**
2784     * Sets the degrees that the view is rotated around the vertical axis through the pivot point.
2785     * Increasing values result in counter-clockwise rotation from the viewpoint of looking
2786     * down the y axis.
2787     *
2788     * <p>Prior to API 11 this will have no effect.</p>
2789     *
2790     * @param value The degrees of Y rotation.
2791     */
2792    public static void setRotationY(View view, float value) {
2793        IMPL.setRotationY(view, value);
2794    }
2795
2796    /**
2797     * Sets the amount that the view is scaled in x around the pivot point, as a proportion of
2798     * the view's unscaled width. A value of 1 means that no scaling is applied.
2799     *
2800     * <p>Prior to API 11 this will have no effect.</p>
2801     *
2802     * @param value The scaling factor.
2803     */
2804    public static void setScaleX(View view, float value) {
2805        IMPL.setScaleX(view, value);
2806    }
2807
2808    /**
2809     * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of
2810     * the view's unscaled width. A value of 1 means that no scaling is applied.
2811     *
2812     * <p>Prior to API 11 this will have no effect.</p>
2813     *
2814     * @param value The scaling factor.
2815     */
2816    public static void setScaleY(View view, float value) {
2817        IMPL.setScaleY(view, value);
2818    }
2819
2820    /**
2821     * The x location of the point around which the view is
2822     * {@link #setRotation(View, float) rotated} and {@link #setScaleX(View, float) scaled}.
2823     *
2824     * <p>Prior to API 11 this will have no effect.</p>
2825     *
2826     */
2827    public static float getPivotX(View view) {
2828        return IMPL.getPivotX(view);
2829    }
2830
2831    /**
2832     * Sets the x location of the point around which the view is
2833     * {@link #setRotation(View, float) rotated} and {@link #setScaleX(View, float) scaled}.
2834     * By default, the pivot point is centered on the object.
2835     * Setting this property disables this behavior and causes the view to use only the
2836     * explicitly set pivotX and pivotY values.
2837     *
2838     * <p>Prior to API 11 this will have no effect.</p>
2839     *
2840     * @param value The x location of the pivot point.
2841     */
2842    public static void setPivotX(View view, float value) {
2843        IMPL.setPivotX(view, value);
2844    }
2845
2846    /**
2847     * The y location of the point around which the view is {@link #setRotation(View,
2848     * float) rotated} and {@link #setScaleY(View, float) scaled}.
2849     *
2850     * <p>Prior to API 11 this will return 0.</p>
2851     *
2852     * @return The y location of the pivot point.
2853     */
2854    public static float getPivotY(View view) {
2855        return IMPL.getPivotY(view);
2856    }
2857
2858    /**
2859     * Sets the y location of the point around which the view is
2860     * {@link #setRotation(View, float) rotated} and {@link #setScaleY(View, float) scaled}.
2861     * By default, the pivot point is centered on the object.
2862     * Setting this property disables this behavior and causes the view to use only the
2863     * explicitly set pivotX and pivotY values.
2864     *
2865     * <p>Prior to API 11 this will have no effect.</p>
2866     *
2867     * @param value The y location of the pivot point.
2868     */
2869    public static void setPivotY(View view, float value) {
2870        IMPL.setPivotY(view, value);
2871    }
2872
2873    public static float getRotation(View view) {
2874        return IMPL.getRotation(view);
2875    }
2876
2877    public static float getRotationX(View view) {
2878        return IMPL.getRotationX(view);
2879    }
2880
2881    public static float getRotationY(View view) {
2882        return IMPL.getRotationY(view);
2883    }
2884
2885    public static float getScaleX(View view) {
2886        return IMPL.getScaleX(view);
2887    }
2888
2889    public static float getScaleY(View view) {
2890        return IMPL.getScaleY(view);
2891    }
2892
2893    public static float getX(View view) {
2894        return IMPL.getX(view);
2895    }
2896
2897    public static float getY(View view) {
2898        return IMPL.getY(view);
2899    }
2900
2901    /**
2902     * Sets the base elevation of this view, in pixels.
2903     */
2904    public static void setElevation(View view, float elevation) {
2905        IMPL.setElevation(view, elevation);
2906    }
2907
2908    /**
2909     * The base elevation of this view relative to its parent, in pixels.
2910     *
2911     * @return The base depth position of the view, in pixels.
2912     */
2913    public static float getElevation(View view) {
2914        return IMPL.getElevation(view);
2915    }
2916
2917    /**
2918     * Sets the depth location of this view relative to its {@link #getElevation(View) elevation}.
2919     */
2920    public static void setTranslationZ(View view, float translationZ) {
2921        IMPL.setTranslationZ(view, translationZ);
2922    }
2923
2924    /**
2925     * The depth location of this view relative to its {@link #getElevation(View) elevation}.
2926     *
2927     * @return The depth of this view relative to its elevation.
2928     */
2929    public static float getTranslationZ(View view) {
2930        return IMPL.getTranslationZ(view);
2931    }
2932
2933    /**
2934     * Sets the name of the View to be used to identify Views in Transitions.
2935     * Names should be unique in the View hierarchy.
2936     *
2937     * @param view The View against which to invoke the method.
2938     * @param transitionName The name of the View to uniquely identify it for Transitions.
2939     */
2940    public static void setTransitionName(View view, String transitionName) {
2941        IMPL.setTransitionName(view, transitionName);
2942    }
2943
2944    /**
2945     * Returns the name of the View to be used to identify Views in Transitions.
2946     * Names should be unique in the View hierarchy.
2947     *
2948     * <p>This returns null if the View has not been given a name.</p>
2949     *
2950     * @param view The View against which to invoke the method.
2951     * @return The name used of the View to be used to identify Views in Transitions or null
2952     * if no name has been given.
2953     */
2954    public static String getTransitionName(View view) {
2955        return IMPL.getTransitionName(view);
2956    }
2957
2958    /**
2959     * Returns the current system UI visibility that is currently set for the entire window.
2960     */
2961    public static int getWindowSystemUiVisibility(View view) {
2962        return IMPL.getWindowSystemUiVisibility(view);
2963    }
2964
2965    /**
2966     * Ask that a new dispatch of {@code View.onApplyWindowInsets(WindowInsets)} be performed. This
2967     * falls back to {@code View.requestFitSystemWindows()} where available.
2968     */
2969    public static void requestApplyInsets(View view) {
2970        IMPL.requestApplyInsets(view);
2971    }
2972
2973    /**
2974     * Tells the ViewGroup whether to draw its children in the order defined by the method
2975     * {@code ViewGroup.getChildDrawingOrder(int, int)}.
2976     *
2977     * @param enabled true if the order of the children when drawing is determined by
2978     *        {@link ViewGroup#getChildDrawingOrder(int, int)}, false otherwise
2979     *
2980     * <p>Prior to API 7 this will have no effect.</p>
2981     */
2982    public static void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) {
2983       IMPL.setChildrenDrawingOrderEnabled(viewGroup, enabled);
2984    }
2985
2986    /**
2987     * Returns true if this view should adapt to fit system window insets. This method will always
2988     * return false before API 16 (Jellybean).
2989     */
2990    public static boolean getFitsSystemWindows(View v) {
2991        return IMPL.getFitsSystemWindows(v);
2992    }
2993
2994    /**
2995     * Sets whether or not this view should account for system screen decorations
2996     * such as the status bar and inset its content; that is, controlling whether
2997     * the default implementation of {@link View#fitSystemWindows(Rect)} will be
2998     * executed. See that method for more details.
2999     */
3000    public static void setFitsSystemWindows(View view, boolean fitSystemWindows) {
3001        IMPL.setFitsSystemWindows(view, fitSystemWindows);
3002    }
3003
3004    /**
3005     * On API 11 devices and above, call <code>Drawable.jumpToCurrentState()</code>
3006     * on all Drawable objects associated with this view.
3007     * <p>
3008     * On API 21 and above, also calls <code>StateListAnimator#jumpToCurrentState()</code>
3009     * if there is a StateListAnimator attached to this view.
3010     */
3011    public static void jumpDrawablesToCurrentState(View v) {
3012        IMPL.jumpDrawablesToCurrentState(v);
3013    }
3014
3015    /**
3016     * Set an {@link OnApplyWindowInsetsListener} to take over the policy for applying
3017     * window insets to this view. This will only take effect on devices with API 21 or above.
3018     */
3019    public static void setOnApplyWindowInsetsListener(View v,
3020            OnApplyWindowInsetsListener listener) {
3021        IMPL.setOnApplyWindowInsetsListener(v, listener);
3022    }
3023
3024    /**
3025     * Called when the view should apply {@link WindowInsetsCompat} according to its internal policy.
3026     *
3027     * <p>Clients may supply an {@link OnApplyWindowInsetsListener} to a view. If one is set
3028     * it will be called during dispatch instead of this method. The listener may optionally
3029     * call this method from its own implementation if it wishes to apply the view's default
3030     * insets policy in addition to its own.</p>
3031     *
3032     * @param view The View against which to invoke the method.
3033     * @param insets Insets to apply
3034     * @return The supplied insets with any applied insets consumed
3035     */
3036    public static WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) {
3037        return IMPL.onApplyWindowInsets(view, insets);
3038    }
3039
3040    /**
3041     * Request to apply the given window insets to this view or another view in its subtree.
3042     *
3043     * <p>This method should be called by clients wishing to apply insets corresponding to areas
3044     * obscured by window decorations or overlays. This can include the status and navigation bars,
3045     * action bars, input methods and more. New inset categories may be added in the future.
3046     * The method returns the insets provided minus any that were applied by this view or its
3047     * children.</p>
3048     *
3049     * @param insets Insets to apply
3050     * @return The provided insets minus the insets that were consumed
3051     */
3052    public static WindowInsetsCompat dispatchApplyWindowInsets(View view,
3053            WindowInsetsCompat insets) {
3054        return IMPL.dispatchApplyWindowInsets(view, insets);
3055    }
3056
3057    /**
3058     * Controls whether the entire hierarchy under this view will save its
3059     * state when a state saving traversal occurs from its parent.
3060     *
3061     * @param enabled Set to false to <em>disable</em> state saving, or true
3062     * (the default) to allow it.
3063     */
3064    public static void setSaveFromParentEnabled(View v, boolean enabled) {
3065        IMPL.setSaveFromParentEnabled(v, enabled);
3066    }
3067
3068    /**
3069     * Changes the activated state of this view. A view can be activated or not.
3070     * Note that activation is not the same as selection.  Selection is
3071     * a transient property, representing the view (hierarchy) the user is
3072     * currently interacting with.  Activation is a longer-term state that the
3073     * user can move views in and out of.
3074     *
3075     * @param activated true if the view must be activated, false otherwise
3076     */
3077    public static void setActivated(View view, boolean activated) {
3078        IMPL.setActivated(view, activated);
3079    }
3080
3081    /**
3082     * Returns whether this View has content which overlaps.
3083     *
3084     * <p>This function, intended to be overridden by specific View types, is an optimization when
3085     * alpha is set on a view. If rendering overlaps in a view with alpha < 1, that view is drawn to
3086     * an offscreen buffer and then composited into place, which can be expensive. If the view has
3087     * no overlapping rendering, the view can draw each primitive with the appropriate alpha value
3088     * directly. An example of overlapping rendering is a TextView with a background image, such as
3089     * a Button. An example of non-overlapping rendering is a TextView with no background, or an
3090     * ImageView with only the foreground image. The default implementation returns true; subclasses
3091     * should override if they have cases which can be optimized.</p>
3092     *
3093     * @return true if the content in this view might overlap, false otherwise.
3094     */
3095    public static boolean hasOverlappingRendering(View view) {
3096        return IMPL.hasOverlappingRendering(view);
3097    }
3098
3099    /**
3100     * Return if the padding as been set through relative values
3101     * {@code View.setPaddingRelative(int, int, int, int)} or thru
3102     *
3103     * @return true if the padding is relative or false if it is not.
3104     */
3105    public static boolean isPaddingRelative(View view) {
3106        return IMPL.isPaddingRelative(view);
3107    }
3108
3109    /**
3110     * Set the background of the {@code view} to a given Drawable, or remove the background. If the
3111     * background has padding, {@code view}'s padding is set to the background's padding. However,
3112     * when a background is removed, this View's padding isn't touched. If setting the padding is
3113     * desired, please use{@code setPadding(int, int, int, int)}.
3114     */
3115    public static void setBackground(View view, Drawable background) {
3116        IMPL.setBackground(view, background);
3117    }
3118
3119    /**
3120     * Return the tint applied to the background drawable, if specified.
3121     * <p>
3122     * Only returns meaningful info when running on API v21 or newer, or if {@code view}
3123     * implements the {@code TintableBackgroundView} interface.
3124     */
3125    public static ColorStateList getBackgroundTintList(View view) {
3126        return IMPL.getBackgroundTintList(view);
3127    }
3128
3129    /**
3130     * Applies a tint to the background drawable.
3131     * <p>
3132     * This will always take effect when running on API v21 or newer. When running on platforms
3133     * previous to API v21, it will only take effect if {@code view} implement the
3134     * {@code TintableBackgroundView} interface.
3135     */
3136    public static void setBackgroundTintList(View view, ColorStateList tintList) {
3137        IMPL.setBackgroundTintList(view, tintList);
3138    }
3139
3140    /**
3141     * Return the blending mode used to apply the tint to the background
3142     * drawable, if specified.
3143     * <p>
3144     * Only returns meaningful info when running on API v21 or newer, or if {@code view}
3145     * implements the {@code TintableBackgroundView} interface.
3146     */
3147    public static PorterDuff.Mode getBackgroundTintMode(View view) {
3148        return IMPL.getBackgroundTintMode(view);
3149    }
3150
3151    /**
3152     * Specifies the blending mode used to apply the tint specified by
3153     * {@link #setBackgroundTintList(android.view.View, android.content.res.ColorStateList)} to
3154     * the background drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}.
3155     * <p>
3156     * This will always take effect when running on API v21 or newer. When running on platforms
3157     * previous to API v21, it will only take effect if {@code view} implement the
3158     * {@code TintableBackgroundView} interface.
3159     */
3160    public static void setBackgroundTintMode(View view, PorterDuff.Mode mode) {
3161        IMPL.setBackgroundTintMode(view, mode);
3162    }
3163    // TODO: getters for various view properties (rotation, etc)
3164
3165    /**
3166     * Enable or disable nested scrolling for this view.
3167     *
3168     * <p>If this property is set to true the view will be permitted to initiate nested
3169     * scrolling operations with a compatible parent view in the current hierarchy. If this
3170     * view does not implement nested scrolling this will have no effect. Disabling nested scrolling
3171     * while a nested scroll is in progress has the effect of
3172     * {@link #stopNestedScroll(View) stopping} the nested scroll.</p>
3173     *
3174     * @param enabled true to enable nested scrolling, false to disable
3175     *
3176     * @see #isNestedScrollingEnabled(View)
3177     */
3178    public static void setNestedScrollingEnabled(View view, boolean enabled) {
3179        IMPL.setNestedScrollingEnabled(view, enabled);
3180    }
3181
3182    /**
3183     * Returns true if nested scrolling is enabled for this view.
3184     *
3185     * <p>If nested scrolling is enabled and this View class implementation supports it,
3186     * this view will act as a nested scrolling child view when applicable, forwarding data
3187     * about the scroll operation in progress to a compatible and cooperating nested scrolling
3188     * parent.</p>
3189     *
3190     * @return true if nested scrolling is enabled
3191     *
3192     * @see #setNestedScrollingEnabled(View, boolean)
3193     */
3194    public static boolean isNestedScrollingEnabled(View view) {
3195        return IMPL.isNestedScrollingEnabled(view);
3196    }
3197
3198    /**
3199     * Begin a nestable scroll operation along the given axes.
3200     *
3201     * <p>A view starting a nested scroll promises to abide by the following contract:</p>
3202     *
3203     * <p>The view will call startNestedScroll upon initiating a scroll operation. In the case
3204     * of a touch scroll this corresponds to the initial {@link MotionEvent#ACTION_DOWN}.
3205     * In the case of touch scrolling the nested scroll will be terminated automatically in
3206     * the same manner as {@link ViewParent#requestDisallowInterceptTouchEvent(boolean)}.
3207     * In the event of programmatic scrolling the caller must explicitly call
3208     * {@link #stopNestedScroll(View)} to indicate the end of the nested scroll.</p>
3209     *
3210     * <p>If <code>startNestedScroll</code> returns true, a cooperative parent was found.
3211     * If it returns false the caller may ignore the rest of this contract until the next scroll.
3212     * Calling startNestedScroll while a nested scroll is already in progress will return true.</p>
3213     *
3214     * <p>At each incremental step of the scroll the caller should invoke
3215     * {@link #dispatchNestedPreScroll(View, int, int, int[], int[]) dispatchNestedPreScroll}
3216     * once it has calculated the requested scrolling delta. If it returns true the nested scrolling
3217     * parent at least partially consumed the scroll and the caller should adjust the amount it
3218     * scrolls by.</p>
3219     *
3220     * <p>After applying the remainder of the scroll delta the caller should invoke
3221     * {@link #dispatchNestedScroll(View, int, int, int, int, int[]) dispatchNestedScroll}, passing
3222     * both the delta consumed and the delta unconsumed. A nested scrolling parent may treat
3223     * these values differently. See
3224     * {@link NestedScrollingParent#onNestedScroll(View, int, int, int, int)}.
3225     * </p>
3226     *
3227     * @param axes Flags consisting of a combination of {@link ViewCompat#SCROLL_AXIS_HORIZONTAL}
3228     *             and/or {@link ViewCompat#SCROLL_AXIS_VERTICAL}.
3229     * @return true if a cooperative parent was found and nested scrolling has been enabled for
3230     *         the current gesture.
3231     *
3232     * @see #stopNestedScroll(View)
3233     * @see #dispatchNestedPreScroll(View, int, int, int[], int[])
3234     * @see #dispatchNestedScroll(View, int, int, int, int, int[])
3235     */
3236    public static boolean startNestedScroll(View view, int axes) {
3237        return IMPL.startNestedScroll(view, axes);
3238    }
3239
3240    /**
3241     * Stop a nested scroll in progress.
3242     *
3243     * <p>Calling this method when a nested scroll is not currently in progress is harmless.</p>
3244     *
3245     * @see #startNestedScroll(View, int)
3246     */
3247    public static void stopNestedScroll(View view) {
3248        IMPL.stopNestedScroll(view);
3249    }
3250
3251    /**
3252     * Returns true if this view has a nested scrolling parent.
3253     *
3254     * <p>The presence of a nested scrolling parent indicates that this view has initiated
3255     * a nested scroll and it was accepted by an ancestor view further up the view hierarchy.</p>
3256     *
3257     * @return whether this view has a nested scrolling parent
3258     */
3259    public static boolean hasNestedScrollingParent(View view) {
3260        return IMPL.hasNestedScrollingParent(view);
3261    }
3262
3263    /**
3264     * Dispatch one step of a nested scroll in progress.
3265     *
3266     * <p>Implementations of views that support nested scrolling should call this to report
3267     * info about a scroll in progress to the current nested scrolling parent. If a nested scroll
3268     * is not currently in progress or nested scrolling is not
3269     * {@link #isNestedScrollingEnabled(View) enabled} for this view this method does nothing.</p>
3270     *
3271     * <p>Compatible View implementations should also call
3272     * {@link #dispatchNestedPreScroll(View, int, int, int[], int[]) dispatchNestedPreScroll} before
3273     * consuming a component of the scroll event themselves.</p>
3274     *
3275     * @param dxConsumed Horizontal distance in pixels consumed by this view during this scroll step
3276     * @param dyConsumed Vertical distance in pixels consumed by this view during this scroll step
3277     * @param dxUnconsumed Horizontal scroll distance in pixels not consumed by this view
3278     * @param dyUnconsumed Horizontal scroll distance in pixels not consumed by this view
3279     * @param offsetInWindow Optional. If not null, on return this will contain the offset
3280     *                       in local view coordinates of this view from before this operation
3281     *                       to after it completes. View implementations may use this to adjust
3282     *                       expected input coordinate tracking.
3283     * @return true if the event was dispatched, false if it could not be dispatched.
3284     * @see #dispatchNestedPreScroll(View, int, int, int[], int[])
3285     */
3286    public static boolean dispatchNestedScroll(View view, int dxConsumed, int dyConsumed,
3287            int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
3288        return IMPL.dispatchNestedScroll(view, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,
3289                offsetInWindow);
3290    }
3291
3292    /**
3293     * Dispatch one step of a nested scroll in progress before this view consumes any portion of it.
3294     *
3295     * <p>Nested pre-scroll events are to nested scroll events what touch intercept is to touch.
3296     * <code>dispatchNestedPreScroll</code> offers an opportunity for the parent view in a nested
3297     * scrolling operation to consume some or all of the scroll operation before the child view
3298     * consumes it.</p>
3299     *
3300     * @param dx Horizontal scroll distance in pixels
3301     * @param dy Vertical scroll distance in pixels
3302     * @param consumed Output. If not null, consumed[0] will contain the consumed component of dx
3303     *                 and consumed[1] the consumed dy.
3304     * @param offsetInWindow Optional. If not null, on return this will contain the offset
3305     *                       in local view coordinates of this view from before this operation
3306     *                       to after it completes. View implementations may use this to adjust
3307     *                       expected input coordinate tracking.
3308     * @return true if the parent consumed some or all of the scroll delta
3309     * @see #dispatchNestedScroll(View, int, int, int, int, int[])
3310     */
3311    public static boolean dispatchNestedPreScroll(View view, int dx, int dy, int[] consumed,
3312            int[] offsetInWindow) {
3313        return IMPL.dispatchNestedPreScroll(view, dx, dy, consumed, offsetInWindow);
3314    }
3315
3316    /**
3317     * Dispatch a fling to a nested scrolling parent.
3318     *
3319     * <p>This method should be used to indicate that a nested scrolling child has detected
3320     * suitable conditions for a fling. Generally this means that a touch scroll has ended with a
3321     * {@link VelocityTracker velocity} in the direction of scrolling that meets or exceeds
3322     * the {@link ViewConfiguration#getScaledMinimumFlingVelocity() minimum fling velocity}
3323     * along a scrollable axis.</p>
3324     *
3325     * <p>If a nested scrolling child view would normally fling but it is at the edge of
3326     * its own content, it can use this method to delegate the fling to its nested scrolling
3327     * parent instead. The parent may optionally consume the fling or observe a child fling.</p>
3328     *
3329     * @param velocityX Horizontal fling velocity in pixels per second
3330     * @param velocityY Vertical fling velocity in pixels per second
3331     * @param consumed true if the child consumed the fling, false otherwise
3332     * @return true if the nested scrolling parent consumed or otherwise reacted to the fling
3333     */
3334    public static boolean dispatchNestedFling(View view, float velocityX, float velocityY,
3335            boolean consumed) {
3336        return IMPL.dispatchNestedFling(view, velocityX, velocityY, consumed);
3337    }
3338
3339    /**
3340     * Dispatch a fling to a nested scrolling parent before it is processed by this view.
3341     *
3342     * <p>Nested pre-fling events are to nested fling events what touch intercept is to touch
3343     * and what nested pre-scroll is to nested scroll. <code>dispatchNestedPreFling</code>
3344     * offsets an opportunity for the parent view in a nested fling to fully consume the fling
3345     * before the child view consumes it. If this method returns <code>true</code>, a nested
3346     * parent view consumed the fling and this view should not scroll as a result.</p>
3347     *
3348     * <p>For a better user experience, only one view in a nested scrolling chain should consume
3349     * the fling at a time. If a parent view consumed the fling this method will return false.
3350     * Custom view implementations should account for this in two ways:</p>
3351     *
3352     * <ul>
3353     *     <li>If a custom view is paged and needs to settle to a fixed page-point, do not
3354     *     call <code>dispatchNestedPreFling</code>; consume the fling and settle to a valid
3355     *     position regardless.</li>
3356     *     <li>If a nested parent does consume the fling, this view should not scroll at all,
3357     *     even to settle back to a valid idle position.</li>
3358     * </ul>
3359     *
3360     * <p>Views should also not offer fling velocities to nested parent views along an axis
3361     * where scrolling is not currently supported; a {@link android.widget.ScrollView ScrollView}
3362     * should not offer a horizontal fling velocity to its parents since scrolling along that
3363     * axis is not permitted and carrying velocity along that motion does not make sense.</p>
3364     *
3365     * @param velocityX Horizontal fling velocity in pixels per second
3366     * @param velocityY Vertical fling velocity in pixels per second
3367     * @return true if a nested scrolling parent consumed the fling
3368     */
3369    public static boolean dispatchNestedPreFling(View view, float velocityX, float velocityY) {
3370        return IMPL.dispatchNestedPreFling(view, velocityX, velocityY);
3371    }
3372
3373    /**
3374     * Returns whether the view hierarchy is currently undergoing a layout pass. This
3375     * information is useful to avoid situations such as calling {@link View#requestLayout()}
3376     * during a layout pass.
3377     * <p>
3378     * Compatibility:
3379     * <ul>
3380     *     <li>API &lt; 18: Always returns {@code false}</li>
3381     * </ul>
3382     *
3383     * @return whether the view hierarchy is currently undergoing a layout pass
3384     */
3385    public static boolean isInLayout(View view) {
3386        return IMPL.isInLayout(view);
3387    }
3388
3389    /**
3390     * Returns true if {@code view} has been through at least one layout since it
3391     * was last attached to or detached from a window.
3392     */
3393    public static boolean isLaidOut(View view) {
3394        return IMPL.isLaidOut(view);
3395    }
3396
3397    /**
3398     * Returns whether layout direction has been resolved.
3399     * <p>
3400     * Compatibility:
3401     * <ul>
3402     *     <li>API &lt; 19: Always returns {@code false}</li>
3403     * </ul>
3404     *
3405     * @return true if layout direction has been resolved.
3406     */
3407    public static boolean isLayoutDirectionResolved(View view) {
3408        return IMPL.isLayoutDirectionResolved(view);
3409    }
3410
3411    /**
3412     * The visual z position of this view, in pixels. This is equivalent to the
3413     * {@link #setTranslationZ(View, float) translationZ} property plus the current
3414     * {@link #getElevation(View) elevation} property.
3415     *
3416     * @return The visual z position of this view, in pixels.
3417     */
3418    public static float getZ(View view) {
3419        return IMPL.getZ(view);
3420    }
3421
3422    /**
3423     * Sets the visual z position of this view, in pixels. This is equivalent to setting the
3424     * {@link #setTranslationZ(View, float) translationZ} property to be the difference between
3425     * the x value passed in and the current {@link #getElevation(View) elevation} property.
3426     * <p>
3427     * Compatibility:
3428     * <ul>
3429     *     <li>API &lt; 21: No-op
3430     * </ul>
3431     *
3432     * @param z The visual z position of this view, in pixels.
3433     */
3434    public static void setZ(View view, float z) {
3435        IMPL.setZ(view, z);
3436    }
3437
3438    /**
3439     * Offset this view's vertical location by the specified number of pixels.
3440     *
3441     * @param offset the number of pixels to offset the view by
3442     */
3443    public static void offsetTopAndBottom(View view, int offset) {
3444        IMPL.offsetTopAndBottom(view, offset);
3445    }
3446
3447    /**
3448     * Offset this view's horizontal location by the specified amount of pixels.
3449     *
3450     * @param offset the number of pixels to offset the view by
3451     */
3452    public static void offsetLeftAndRight(View view, int offset) {
3453        IMPL.offsetLeftAndRight(view, offset);
3454    }
3455
3456    /**
3457     * Sets a rectangular area on this view to which the view will be clipped
3458     * when it is drawn. Setting the value to null will remove the clip bounds
3459     * and the view will draw normally, using its full bounds.
3460     *
3461     * <p>Prior to API 18 this does nothing.</p>
3462     *
3463     * @param view       The view to set clipBounds.
3464     * @param clipBounds The rectangular area, in the local coordinates of
3465     * this view, to which future drawing operations will be clipped.
3466     */
3467    public static void setClipBounds(View view, Rect clipBounds) {
3468        IMPL.setClipBounds(view, clipBounds);
3469    }
3470
3471    /**
3472     * Returns a copy of the current {@link #setClipBounds(View, Rect)}.
3473     *
3474     * <p>Prior to API 18 this will return null.</p>
3475     *
3476     * @return A copy of the current clip bounds if clip bounds are set,
3477     * otherwise null.
3478     */
3479    public static Rect getClipBounds(View view) {
3480        return IMPL.getClipBounds(view);
3481    }
3482
3483    /**
3484     * Returns true if the provided view is currently attached to a window.
3485     */
3486    public static boolean isAttachedToWindow(View view) {
3487        return IMPL.isAttachedToWindow(view);
3488    }
3489
3490    /**
3491     * Returns whether the provided view has an attached {@link View.OnClickListener}.
3492     *
3493     * @return true if there is a listener, false if there is none.
3494     */
3495    public static boolean hasOnClickListeners(View view) {
3496        return IMPL.hasOnClickListeners(view);
3497    }
3498
3499    /**
3500     * Sets the state of all scroll indicators.
3501     * <p>
3502     * See {@link #setScrollIndicators(View, int, int)} for usage information.
3503     *
3504     * @param indicators a bitmask of indicators that should be enabled, or
3505     *                   {@code 0} to disable all indicators
3506     *
3507     * @see #setScrollIndicators(View, int, int)
3508     * @see #getScrollIndicators(View)
3509     */
3510    public static void setScrollIndicators(@NonNull View view, @ScrollIndicators int indicators) {
3511        IMPL.setScrollIndicators(view, indicators);
3512    }
3513
3514    /**
3515     * Sets the state of the scroll indicators specified by the mask. To change
3516     * all scroll indicators at once, see {@link #setScrollIndicators(View, int)}.
3517     * <p>
3518     * When a scroll indicator is enabled, it will be displayed if the view
3519     * can scroll in the direction of the indicator.
3520     * <p>
3521     * Multiple indicator types may be enabled or disabled by passing the
3522     * logical OR of the desired types. If multiple types are specified, they
3523     * will all be set to the same enabled state.
3524     * <p>
3525     * For example, to enable the top scroll indicatorExample: {@code setScrollIndicators}
3526     *
3527     * @param indicators the indicator direction, or the logical OR of multiple
3528     *             indicator directions. One or more of:
3529     *             <ul>
3530     *               <li>{@link #SCROLL_INDICATOR_TOP}</li>
3531     *               <li>{@link #SCROLL_INDICATOR_BOTTOM}</li>
3532     *               <li>{@link #SCROLL_INDICATOR_LEFT}</li>
3533     *               <li>{@link #SCROLL_INDICATOR_RIGHT}</li>
3534     *               <li>{@link #SCROLL_INDICATOR_START}</li>
3535     *               <li>{@link #SCROLL_INDICATOR_END}</li>
3536     *             </ul>
3537     *
3538     * @see #setScrollIndicators(View, int)
3539     * @see #getScrollIndicators(View)
3540     */
3541    public static void setScrollIndicators(@NonNull View view, @ScrollIndicators int indicators,
3542            @ScrollIndicators int mask) {
3543        IMPL.setScrollIndicators(view, indicators, mask);
3544    }
3545
3546    /**
3547     * Returns a bitmask representing the enabled scroll indicators.
3548     * <p>
3549     * For example, if the top and left scroll indicators are enabled and all
3550     * other indicators are disabled, the return value will be
3551     * {@code ViewCompat.SCROLL_INDICATOR_TOP | ViewCompat.SCROLL_INDICATOR_LEFT}.
3552     * <p>
3553     * To check whether the bottom scroll indicator is enabled, use the value
3554     * of {@code (ViewCompat.getScrollIndicators(view) & ViewCompat.SCROLL_INDICATOR_BOTTOM) != 0}.
3555     *
3556     * @return a bitmask representing the enabled scroll indicators
3557     */
3558    public static int getScrollIndicators(@NonNull View view) {
3559        return IMPL.getScrollIndicators(view);
3560    }
3561
3562    /**
3563     * Set the pointer icon for the current view.
3564     * @param pointerIcon A PointerIconCompat instance which will be shown when the mouse hovers.
3565     */
3566    public static void setPointerIcon(@NonNull View view, PointerIconCompat pointerIcon) {
3567        IMPL.setPointerIcon(view, pointerIcon);
3568    }
3569
3570    /**
3571     * Gets the logical display to which the view's window has been attached.
3572     * <p>
3573     * Compatibility:
3574     * <ul>
3575     * <li>API &lt; 17: Returns the default display when the view is attached. Otherwise, null.
3576     * </ul>
3577     *
3578     * @return The logical display, or null if the view is not currently attached to a window.
3579     */
3580    public static Display getDisplay(@NonNull View view) {
3581        return IMPL.getDisplay(view);
3582    }
3583
3584    protected ViewCompat() {}
3585}
3586