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