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