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