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