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