ViewCompat.java revision f9c35128decbd812ff2497852ccacbd1ffbbd811
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.graphics.Paint;
20import android.graphics.PixelFormat;
21import android.graphics.Rect;
22import android.graphics.drawable.Drawable;
23import android.os.Bundle;
24import android.support.annotation.IdRes;
25import android.support.annotation.IntDef;
26import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
27import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
28import android.util.Log;
29import android.view.View;
30import android.view.ViewGroup;
31import android.view.ViewParent;
32import android.view.accessibility.AccessibilityEvent;
33
34import java.lang.annotation.Retention;
35import java.lang.annotation.RetentionPolicy;
36import java.lang.reflect.Field;
37import java.lang.reflect.Method;
38import java.util.WeakHashMap;
39
40/**
41 * Helper for accessing features in {@link View} introduced after API
42 * level 4 in a backwards compatible fashion.
43 */
44public class ViewCompat {
45    private static final String TAG = "ViewCompat";
46
47    /** @hide */
48    @IntDef({OVER_SCROLL_ALWAYS, OVER_SCROLL_IF_CONTENT_SCROLLS, OVER_SCROLL_IF_CONTENT_SCROLLS})
49    @Retention(RetentionPolicy.SOURCE)
50    private @interface OverScroll {}
51
52    /**
53     * Always allow a user to over-scroll this view, provided it is a
54     * view that can scroll.
55     */
56    public static final int OVER_SCROLL_ALWAYS = 0;
57
58    /**
59     * Allow a user to over-scroll this view only if the content is large
60     * enough to meaningfully scroll, provided it is a view that can scroll.
61     */
62    public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1;
63
64    /**
65     * Never allow a user to over-scroll this view.
66     */
67    public static final int OVER_SCROLL_NEVER = 2;
68
69    private static final long FAKE_FRAME_TIME = 10;
70
71    /** @hide */
72    @IntDef({
73            IMPORTANT_FOR_ACCESSIBILITY_AUTO,
74            IMPORTANT_FOR_ACCESSIBILITY_YES,
75            IMPORTANT_FOR_ACCESSIBILITY_NO,
76            IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
77    })
78    @Retention(RetentionPolicy.SOURCE)
79    private @interface ImportantForAccessibility {}
80
81    /**
82     * Automatically determine whether a view is important for accessibility.
83     */
84    public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000;
85
86    /**
87     * The view is important for accessibility.
88     */
89    public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001;
90
91    /**
92     * The view is not important for accessibility.
93     */
94    public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002;
95
96    /**
97     * The view is not important for accessibility, nor are any of its
98     * descendant views.
99     */
100    public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004;
101
102    /** @hide */
103    @IntDef({
104            ACCESSIBILITY_LIVE_REGION_NONE,
105            ACCESSIBILITY_LIVE_REGION_POLITE,
106            ACCESSIBILITY_LIVE_REGION_ASSERTIVE
107    })
108    @Retention(RetentionPolicy.SOURCE)
109    private @interface AccessibilityLiveRegion {}
110
111    /**
112     * Live region mode specifying that accessibility services should not
113     * automatically announce changes to this view. This is the default live
114     * region mode for most views.
115     * <p>
116     * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}.
117     */
118    public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000;
119
120    /**
121     * Live region mode specifying that accessibility services should announce
122     * changes to this view.
123     * <p>
124     * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}.
125     */
126    public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001;
127
128    /**
129     * Live region mode specifying that accessibility services should interrupt
130     * ongoing speech to immediately announce changes to this view.
131     * <p>
132     * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}.
133     */
134    public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002;
135
136    /** @hide */
137    @IntDef({LAYER_TYPE_NONE, LAYER_TYPE_SOFTWARE, LAYER_TYPE_HARDWARE})
138    @Retention(RetentionPolicy.SOURCE)
139    private @interface LayerType {}
140
141    /**
142     * Indicates that the view does not have a layer.
143     */
144    public static final int LAYER_TYPE_NONE = 0;
145
146    /**
147     * <p>Indicates that the view has a software layer. A software layer is backed
148     * by a bitmap and causes the view to be rendered using Android's software
149     * rendering pipeline, even if hardware acceleration is enabled.</p>
150     *
151     * <p>Software layers have various usages:</p>
152     * <p>When the application is not using hardware acceleration, a software layer
153     * is useful to apply a specific color filter and/or blending mode and/or
154     * translucency to a view and all its children.</p>
155     * <p>When the application is using hardware acceleration, a software layer
156     * is useful to render drawing primitives not supported by the hardware
157     * accelerated pipeline. It can also be used to cache a complex view tree
158     * into a texture and reduce the complexity of drawing operations. For instance,
159     * when animating a complex view tree with a translation, a software layer can
160     * be used to render the view tree only once.</p>
161     * <p>Software layers should be avoided when the affected view tree updates
162     * often. Every update will require to re-render the software layer, which can
163     * potentially be slow (particularly when hardware acceleration is turned on
164     * since the layer will have to be uploaded into a hardware texture after every
165     * update.)</p>
166     */
167    public static final int LAYER_TYPE_SOFTWARE = 1;
168
169    /**
170     * <p>Indicates that the view has a hardware layer. A hardware layer is backed
171     * by a hardware specific texture (generally Frame Buffer Objects or FBO on
172     * OpenGL hardware) and causes the view to be rendered using Android's hardware
173     * rendering pipeline, but only if hardware acceleration is turned on for the
174     * view hierarchy. When hardware acceleration is turned off, hardware layers
175     * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
176     *
177     * <p>A hardware layer is useful to apply a specific color filter and/or
178     * blending mode and/or translucency to a view and all its children.</p>
179     * <p>A hardware layer can be used to cache a complex view tree into a
180     * texture and reduce the complexity of drawing operations. For instance,
181     * when animating a complex view tree with a translation, a hardware layer can
182     * be used to render the view tree only once.</p>
183     * <p>A hardware layer can also be used to increase the rendering quality when
184     * rotation transformations are applied on a view. It can also be used to
185     * prevent potential clipping issues when applying 3D transforms on a view.</p>
186     */
187    public static final int LAYER_TYPE_HARDWARE = 2;
188
189    /** @hide */
190    @IntDef({
191            LAYOUT_DIRECTION_LTR,
192            LAYOUT_DIRECTION_RTL,
193            LAYOUT_DIRECTION_INHERIT,
194            LAYOUT_DIRECTION_LOCALE})
195    @Retention(RetentionPolicy.SOURCE)
196    private @interface LayoutDirectionMode {}
197
198    /** @hide */
199    @IntDef({
200            LAYOUT_DIRECTION_LTR,
201            LAYOUT_DIRECTION_RTL
202    })
203    @Retention(RetentionPolicy.SOURCE)
204    private @interface ResolvedLayoutDirectionMode {}
205
206    /**
207     * Horizontal layout direction of this view is from Left to Right.
208     */
209    public static final int LAYOUT_DIRECTION_LTR = 0;
210
211    /**
212     * Horizontal layout direction of this view is from Right to Left.
213     */
214    public static final int LAYOUT_DIRECTION_RTL = 1;
215
216    /**
217     * Horizontal layout direction of this view is inherited from its parent.
218     * Use with {@link #setLayoutDirection}.
219     */
220    public static final int LAYOUT_DIRECTION_INHERIT = 2;
221
222    /**
223     * Horizontal layout direction of this view is from deduced from the default language
224     * script for the locale. Use with {@link #setLayoutDirection}.
225     */
226    public static final int LAYOUT_DIRECTION_LOCALE = 3;
227
228    /**
229     * Bits of {@link #getMeasuredWidthAndState} and
230     * {@link #getMeasuredWidthAndState} that provide the actual measured size.
231     */
232    public static final int MEASURED_SIZE_MASK = 0x00ffffff;
233
234    /**
235     * Bits of {@link #getMeasuredWidthAndState} and
236     * {@link #getMeasuredWidthAndState} that provide the additional state bits.
237     */
238    public static final int MEASURED_STATE_MASK = 0xff000000;
239
240    /**
241     * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits
242     * for functions that combine both width and height into a single int,
243     * such as {@link #getMeasuredState} and the childState argument of
244     * {@link #resolveSizeAndState(int, int, int)}.
245     */
246    public static final int MEASURED_HEIGHT_STATE_SHIFT = 16;
247
248    /**
249     * Bit of {@link #getMeasuredWidthAndState} and
250     * {@link #getMeasuredWidthAndState} that indicates the measured size
251     * is smaller that the space the view would like to have.
252     */
253    public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
254
255    interface ViewCompatImpl {
256        public boolean canScrollHorizontally(View v, int direction);
257        public boolean canScrollVertically(View v, int direction);
258        public int getOverScrollMode(View v);
259        public void setOverScrollMode(View v, int mode);
260        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event);
261        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event);
262        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info);
263        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate);
264        public boolean hasAccessibilityDelegate(View v);
265        public boolean hasTransientState(View view);
266        public void setHasTransientState(View view, boolean hasTransientState);
267        public void postInvalidateOnAnimation(View view);
268        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom);
269        public void postOnAnimation(View view, Runnable action);
270        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis);
271        public int getImportantForAccessibility(View view);
272        public void setImportantForAccessibility(View view, int mode);
273        public boolean performAccessibilityAction(View view, int action, Bundle arguments);
274        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view);
275        public float getAlpha(View view);
276        public void setLayerType(View view, int layerType, Paint paint);
277        public int getLayerType(View view);
278        public int getLabelFor(View view);
279        public void setLabelFor(View view, int id);
280        public void setLayerPaint(View view, Paint paint);
281        public int getLayoutDirection(View view);
282        public void setLayoutDirection(View view, int layoutDirection);
283        public ViewParent getParentForAccessibility(View view);
284        public boolean isOpaque(View view);
285        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState);
286        public int getMeasuredWidthAndState(View view);
287        public int getMeasuredHeightAndState(View view);
288        public int getMeasuredState(View view);
289        public int getAccessibilityLiveRegion(View view);
290        public void setAccessibilityLiveRegion(View view, int mode);
291        public int getPaddingStart(View view);
292        public int getPaddingEnd(View view);
293        public void setPaddingRelative(View view, int start, int top, int end, int bottom);
294        public void dispatchStartTemporaryDetach(View view);
295        public void dispatchFinishTemporaryDetach(View view);
296        public float getX(View view);
297        public float getY(View view);
298        public float getRotation(View view);
299        public float getRotationX(View view);
300        public float getRotationY(View view);
301        public float getScaleX(View view);
302        public float getScaleY(View view);
303        public float getTranslationX(View view);
304        public float getTranslationY(View view);
305        public int getMinimumWidth(View view);
306        public int getMinimumHeight(View view);
307        public ViewPropertyAnimatorCompat animate(View view);
308        public void setRotation(View view, float value);
309        public void setRotationX(View view, float value);
310        public void setRotationY(View view, float value);
311        public void setScaleX(View view, float value);
312        public void setScaleY(View view, float value);
313        public void setTranslationX(View view, float value);
314        public void setTranslationY(View view, float value);
315        public void setX(View view, float value);
316        public void setY(View view, float value);
317        public void setAlpha(View view, float value);
318        public void setPivotX(View view, float value);
319        public void setPivotY(View view, float value);
320        public float getPivotX(View view);
321        public float getPivotY(View view);
322        public void setElevation(View view, float elevation);
323        public float getElevation(View view);
324        public void setTranslationZ(View view, float translationZ);
325        public float getTranslationZ(View view);
326        public void setTransitionName(View view, String transitionName);
327        public String getTransitionName(View view);
328        public int getWindowSystemUiVisibility(View view);
329        public void requestApplyInsets(View view);
330        public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled);
331        public boolean getFitsSystemWindows(View view);
332    }
333
334    static class BaseViewCompatImpl implements ViewCompatImpl {
335        private Method mDispatchStartTemporaryDetach;
336        private Method mDispatchFinishTemporaryDetach;
337        private boolean mTempDetachBound;
338        WeakHashMap<View, ViewPropertyAnimatorCompat> mViewPropertyAnimatorCompatMap = null;
339
340
341        public boolean canScrollHorizontally(View v, int direction) {
342            return false;
343        }
344        public boolean canScrollVertically(View v, int direction) {
345            return false;
346        }
347        public int getOverScrollMode(View v) {
348            return OVER_SCROLL_NEVER;
349        }
350        public void setOverScrollMode(View v, int mode) {
351            // Do nothing; API doesn't exist
352        }
353        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
354            // Do nothing; API doesn't exist
355        }
356
357        @Override
358        public boolean hasAccessibilityDelegate(View v) {
359            return false;
360        }
361
362        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
363            // Do nothing; API doesn't exist
364        }
365        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
366         // Do nothing; API doesn't exist
367        }
368        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
369            // Do nothing; API doesn't exist
370        }
371        public boolean hasTransientState(View view) {
372            // A view can't have transient state if transient state wasn't supported.
373            return false;
374        }
375        public void setHasTransientState(View view, boolean hasTransientState) {
376            // Do nothing; API doesn't exist
377        }
378        public void postInvalidateOnAnimation(View view) {
379            view.invalidate();
380        }
381        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) {
382            view.invalidate(left, top, right, bottom);
383        }
384        public void postOnAnimation(View view, Runnable action) {
385            view.postDelayed(action, getFrameTime());
386        }
387        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
388            view.postDelayed(action, getFrameTime() + delayMillis);
389        }
390        long getFrameTime() {
391            return FAKE_FRAME_TIME;
392        }
393        public int getImportantForAccessibility(View view) {
394            return 0;
395        }
396        public void setImportantForAccessibility(View view, int mode) {
397
398        }
399        public boolean performAccessibilityAction(View view, int action, Bundle arguments) {
400            return false;
401        }
402        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
403            return null;
404        }
405        public float getAlpha(View view) {
406            return 1.0f;
407        }
408        public void setLayerType(View view, int layerType, Paint paint) {
409            // No-op until layers became available (HC)
410        }
411        public int getLayerType(View view) {
412            return LAYER_TYPE_NONE;
413        }
414        public int getLabelFor(View view) {
415            return 0;
416        }
417        public void setLabelFor(View view, int id) {
418
419        }
420        public void setLayerPaint(View view, Paint p) {
421            // No-op until layers became available (HC)
422        }
423
424        @Override
425        public int getLayoutDirection(View view) {
426            return LAYOUT_DIRECTION_LTR;
427        }
428
429        @Override
430        public void setLayoutDirection(View view, int layoutDirection) {
431            // No-op
432        }
433
434        @Override
435        public ViewParent getParentForAccessibility(View view) {
436            return view.getParent();
437        }
438
439        @Override
440        public boolean isOpaque(View view) {
441            final Drawable bg = view.getBackground();
442            if (bg != null) {
443                return bg.getOpacity() == PixelFormat.OPAQUE;
444            }
445            return false;
446        }
447
448        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
449            return View.resolveSize(size, measureSpec);
450        }
451
452        @Override
453        public int getMeasuredWidthAndState(View view) {
454            return view.getMeasuredWidth();
455        }
456
457        @Override
458        public int getMeasuredHeightAndState(View view) {
459            return view.getMeasuredHeight();
460        }
461
462        @Override
463        public int getMeasuredState(View view) {
464            return 0;
465        }
466
467        @Override
468        public int getAccessibilityLiveRegion(View view) {
469            return ACCESSIBILITY_LIVE_REGION_NONE;
470        }
471
472        @Override
473        public void setAccessibilityLiveRegion(View view, int mode) {
474            // No-op
475        }
476
477        @Override
478        public int getPaddingStart(View view) {
479            return view.getPaddingLeft();
480        }
481
482        @Override
483        public int getPaddingEnd(View view) {
484            return view.getPaddingRight();
485        }
486
487        @Override
488        public void setPaddingRelative(View view, int start, int top, int end, int bottom) {
489            view.setPadding(start, top, end, bottom);
490        }
491
492        @Override
493        public void dispatchStartTemporaryDetach(View view) {
494            if (!mTempDetachBound) {
495                bindTempDetach();
496            }
497            if (mDispatchStartTemporaryDetach != null) {
498                try {
499                    mDispatchStartTemporaryDetach.invoke(view);
500                } catch (Exception e) {
501                    Log.d(TAG, "Error calling dispatchStartTemporaryDetach", e);
502                }
503            } else {
504                // Try this instead
505                view.onStartTemporaryDetach();
506            }
507        }
508
509        @Override
510        public void dispatchFinishTemporaryDetach(View view) {
511            if (!mTempDetachBound) {
512                bindTempDetach();
513            }
514            if (mDispatchFinishTemporaryDetach != null) {
515                try {
516                    mDispatchFinishTemporaryDetach.invoke(view);
517                } catch (Exception e) {
518                    Log.d(TAG, "Error calling dispatchFinishTemporaryDetach", e);
519                }
520            } else {
521                // Try this instead
522                view.onFinishTemporaryDetach();
523            }
524        }
525
526        private void bindTempDetach() {
527            try {
528                mDispatchStartTemporaryDetach = View.class.getDeclaredMethod(
529                        "dispatchStartTemporaryDetach");
530                mDispatchFinishTemporaryDetach = View.class.getDeclaredMethod(
531                        "dispatchFinishTemporaryDetach");
532            } catch (NoSuchMethodException e) {
533                Log.e(TAG, "Couldn't find method", e);
534            }
535            mTempDetachBound = true;
536        }
537
538        @Override
539        public float getTranslationX(View view) {
540            return 0;
541        }
542
543        @Override
544        public float getTranslationY(View view) {
545            return 0;
546        }
547
548        @Override
549        public float getX(View view) {
550            return 0;
551        }
552
553        @Override
554        public float getY(View view) {
555            return 0;
556        }
557
558        @Override
559        public float getRotation(View view) {
560            return 0;
561        }
562
563        @Override
564        public float getRotationX(View view) {
565            return 0;
566        }
567
568        @Override
569        public float getRotationY(View view) {
570            return 0;
571        }
572
573        @Override
574        public float getScaleX(View view) {
575            return 0;
576        }
577
578        @Override
579        public float getScaleY(View view) {
580            return 0;
581        }
582
583        @Override
584        public int getMinimumWidth(View view) {
585            return 0;
586        }
587
588        @Override
589        public int getMinimumHeight(View view) {
590            return 0;
591        }
592
593        @Override
594        public ViewPropertyAnimatorCompat animate(View view) {
595            return new ViewPropertyAnimatorCompat(view);
596        }
597
598        @Override
599        public void setRotation(View view, float value) {
600            // noop
601        }
602
603        @Override
604        public void setTranslationX(View view, float value) {
605            // noop
606        }
607
608        @Override
609        public void setTranslationY(View view, float value) {
610            // noop
611        }
612
613        @Override
614        public void setAlpha(View view, float value) {
615            // noop
616        }
617
618        @Override
619        public void setRotationX(View view, float value) {
620            // noop
621        }
622
623        @Override
624        public void setRotationY(View view, float value) {
625            // noop
626        }
627
628        @Override
629        public void setScaleX(View view, float value) {
630            // noop
631        }
632
633        @Override
634        public void setScaleY(View view, float value) {
635            // noop
636        }
637
638        @Override
639        public void setX(View view, float value) {
640            // noop
641        }
642
643        @Override
644        public void setY(View view, float value) {
645            // noop
646        }
647
648        @Override
649        public void setPivotX(View view, float value) {
650            // noop
651        }
652
653        @Override
654        public void setPivotY(View view, float value) {
655            // noop
656        }
657
658        @Override
659        public float getPivotX(View view) {
660            return 0;
661        }
662
663        @Override
664        public float getPivotY(View view) {
665            return 0;
666        }
667
668        @Override
669        public void setTransitionName(View view, String transitionName) {
670        }
671
672        @Override
673        public String getTransitionName(View view) {
674            return null;
675        }
676
677        @Override
678        public int getWindowSystemUiVisibility(View view) {
679            return 0;
680        }
681
682        @Override
683        public void requestApplyInsets(View view) {
684        }
685
686        @Override
687        public void setElevation(View view, float elevation) {
688        }
689
690        @Override
691        public float getElevation(View view) {
692            return 0f;
693        }
694
695        @Override
696        public void setTranslationZ(View view, float translationZ) {
697        }
698
699        @Override
700        public float getTranslationZ(View view) {
701            return 0f;
702        }
703
704        @Override
705        public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) {
706            // noop
707        }
708
709        @Override
710        public boolean getFitsSystemWindows(View view) {
711            return false;
712        }
713    }
714
715    static class EclairMr1ViewCompatImpl extends BaseViewCompatImpl {
716        @Override
717        public boolean isOpaque(View view) {
718            return ViewCompatEclairMr1.isOpaque(view);
719        }
720
721        @Override
722        public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) {
723            ViewCompatEclairMr1.setChildrenDrawingOrderEnabled(viewGroup, enabled);
724        }
725    }
726
727    static class GBViewCompatImpl extends EclairMr1ViewCompatImpl {
728        @Override
729        public int getOverScrollMode(View v) {
730            return ViewCompatGingerbread.getOverScrollMode(v);
731        }
732        @Override
733        public void setOverScrollMode(View v, int mode) {
734            ViewCompatGingerbread.setOverScrollMode(v, mode);
735        }
736    }
737
738    static class HCViewCompatImpl extends GBViewCompatImpl {
739        @Override
740        long getFrameTime() {
741            return ViewCompatHC.getFrameTime();
742        }
743        @Override
744        public float getAlpha(View view) {
745            return ViewCompatHC.getAlpha(view);
746        }
747        @Override
748        public void setLayerType(View view, int layerType, Paint paint) {
749            ViewCompatHC.setLayerType(view, layerType, paint);
750        }
751        @Override
752        public int getLayerType(View view)  {
753            return ViewCompatHC.getLayerType(view);
754        }
755        @Override
756        public void setLayerPaint(View view, Paint paint) {
757            // Make sure the paint is correct; this will be cheap if it's the same
758            // instance as was used to call setLayerType earlier.
759            setLayerType(view, getLayerType(view), paint);
760            // This is expensive, but the only way to accomplish this before JB-MR1.
761            view.invalidate();
762        }
763        @Override
764        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
765            return ViewCompatHC.resolveSizeAndState(size, measureSpec, childMeasuredState);
766        }
767        @Override
768        public int getMeasuredWidthAndState(View view) {
769            return ViewCompatHC.getMeasuredWidthAndState(view);
770        }
771        @Override
772        public int getMeasuredHeightAndState(View view) {
773            return ViewCompatHC.getMeasuredHeightAndState(view);
774        }
775        @Override
776        public int getMeasuredState(View view) {
777            return ViewCompatHC.getMeasuredState(view);
778        }
779        @Override
780        public float getTranslationX(View view) {
781            return ViewCompatHC.getTranslationX(view);
782        }
783        @Override
784        public float getTranslationY(View view) {
785            return ViewCompatHC.getTranslationY(view);
786        }
787        @Override
788        public void setTranslationX(View view, float value) {
789            ViewCompatHC.setTranslationX(view, value);
790        }
791        @Override
792        public void setTranslationY(View view, float value) {
793            ViewCompatHC.setTranslationY(view, value);
794        }
795        @Override
796        public void setAlpha(View view, float value) {
797            ViewCompatHC.setAlpha(view, value);
798        }
799        @Override
800        public void setX(View view, float value) {
801            ViewCompatHC.setX(view, value);
802        }
803        @Override
804        public void setY(View view, float value) {
805            ViewCompatHC.setY(view, value);
806        }
807        @Override
808        public void setRotation(View view, float value) {
809            ViewCompatHC.setRotation(view, value);
810        }
811        @Override
812        public void setRotationX(View view, float value) {
813            ViewCompatHC.setRotationX(view, value);
814        }
815        @Override
816        public void setRotationY(View view, float value) {
817            ViewCompatHC.setRotationY(view, value);
818        }
819        @Override
820        public void setScaleX(View view, float value) {
821            ViewCompatHC.setScaleX(view, value);
822        }
823        @Override
824        public void setScaleY(View view, float value) {
825            ViewCompatHC.setScaleY(view, value);
826        }
827        @Override
828        public void setPivotX(View view, float value) {
829            ViewCompatHC.setPivotX(view, value);
830        }
831        @Override
832        public void setPivotY(View view, float value) {
833            ViewCompatHC.setPivotY(view, value);
834        }
835        @Override
836        public float getX(View view) {
837            return ViewCompatHC.getX(view);
838        }
839
840        @Override
841        public float getY(View view) {
842            return ViewCompatHC.getY(view);
843        }
844
845        @Override
846        public float getRotation(View view) {
847            return ViewCompatHC.getRotation(view);
848        }
849
850        @Override
851        public float getRotationX(View view) {
852            return ViewCompatHC.getRotationX(view);
853        }
854
855        @Override
856        public float getRotationY(View view) {
857            return ViewCompatHC.getRotationY(view);
858        }
859
860        @Override
861        public float getScaleX(View view) {
862            return ViewCompatHC.getScaleX(view);
863        }
864
865        @Override
866        public float getScaleY(View view) {
867            return ViewCompatHC.getScaleY(view);
868        }
869
870        @Override
871        public float getPivotX(View view) {
872            return ViewCompatHC.getPivotX(view);
873        }
874        @Override
875        public float getPivotY(View view) {
876            return ViewCompatHC.getPivotY(view);
877        }
878    }
879
880    static class ICSViewCompatImpl extends HCViewCompatImpl {
881        static Field mAccessibilityDelegateField;
882        static boolean accessibilityDelegateCheckFailed = false;
883        @Override
884        public boolean canScrollHorizontally(View v, int direction) {
885            return ViewCompatICS.canScrollHorizontally(v, direction);
886        }
887        @Override
888        public boolean canScrollVertically(View v, int direction) {
889            return ViewCompatICS.canScrollVertically(v, direction);
890        }
891        @Override
892        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
893            ViewCompatICS.onPopulateAccessibilityEvent(v, event);
894        }
895        @Override
896        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
897            ViewCompatICS.onInitializeAccessibilityEvent(v, event);
898        }
899        @Override
900        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
901            ViewCompatICS.onInitializeAccessibilityNodeInfo(v, info.getInfo());
902        }
903        @Override
904        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
905            ViewCompatICS.setAccessibilityDelegate(v, delegate.getBridge());
906        }
907
908        @Override
909        public boolean hasAccessibilityDelegate(View v) {
910            if (accessibilityDelegateCheckFailed) {
911                return false; // View implementation might have changed.
912            }
913            if (mAccessibilityDelegateField == null) {
914                try {
915                    mAccessibilityDelegateField = View.class
916                            .getDeclaredField("mAccessibilityDelegate");
917                    mAccessibilityDelegateField.setAccessible(true);
918                } catch (Throwable t) {
919                    accessibilityDelegateCheckFailed = true;
920                    return false;
921                }
922            }
923            try {
924                return mAccessibilityDelegateField.get(v) != null;
925            } catch (Throwable t) {
926                accessibilityDelegateCheckFailed = true;
927                return false;
928            }
929        }
930
931        @Override
932        public ViewPropertyAnimatorCompat animate(View view) {
933            if (mViewPropertyAnimatorCompatMap == null) {
934                mViewPropertyAnimatorCompatMap =
935                        new WeakHashMap<View, ViewPropertyAnimatorCompat>();
936            }
937            ViewPropertyAnimatorCompat vpa = mViewPropertyAnimatorCompatMap.get(view);
938            if (vpa == null) {
939                vpa = new ViewPropertyAnimatorCompat(view);
940                mViewPropertyAnimatorCompatMap.put(view, vpa);
941            }
942            return vpa;
943        }
944    }
945
946    static class JBViewCompatImpl extends ICSViewCompatImpl {
947        @Override
948        public boolean hasTransientState(View view) {
949            return ViewCompatJB.hasTransientState(view);
950        }
951        @Override
952        public void setHasTransientState(View view, boolean hasTransientState) {
953            ViewCompatJB.setHasTransientState(view, hasTransientState);
954        }
955        @Override
956        public void postInvalidateOnAnimation(View view) {
957            ViewCompatJB.postInvalidateOnAnimation(view);
958        }
959        @Override
960        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) {
961            ViewCompatJB.postInvalidateOnAnimation(view, left, top, right, bottom);
962        }
963        @Override
964        public void postOnAnimation(View view, Runnable action) {
965            ViewCompatJB.postOnAnimation(view, action);
966        }
967        @Override
968        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
969            ViewCompatJB.postOnAnimationDelayed(view, action, delayMillis);
970        }
971        @Override
972        public int getImportantForAccessibility(View view) {
973            return ViewCompatJB.getImportantForAccessibility(view);
974        }
975        @Override
976        public void setImportantForAccessibility(View view, int mode) {
977            // IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS is not available
978            // on this platform so replace with IMPORTANT_FOR_ACCESSIBILITY_NO
979            // which is closer semantically.
980            if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
981                mode = IMPORTANT_FOR_ACCESSIBILITY_NO;
982            }
983            ViewCompatJB.setImportantForAccessibility(view, mode);
984        }
985        @Override
986        public boolean performAccessibilityAction(View view, int action, Bundle arguments) {
987            return ViewCompatJB.performAccessibilityAction(view, action, arguments);
988        }
989        @Override
990        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
991            Object compat = ViewCompatJB.getAccessibilityNodeProvider(view);
992            if (compat != null) {
993                return new AccessibilityNodeProviderCompat(compat);
994            }
995            return null;
996        }
997
998        @Override
999        public ViewParent getParentForAccessibility(View view) {
1000            return ViewCompatJB.getParentForAccessibility(view);
1001        }
1002
1003        @Override
1004        public int getMinimumWidth(View view) {
1005            return ViewCompatJB.getMinimumWidth(view);
1006        }
1007
1008        @Override
1009        public int getMinimumHeight(View view) {
1010            return ViewCompatJB.getMinimumHeight(view);
1011        }
1012
1013        @Override
1014        public void requestApplyInsets(View view) {
1015            ViewCompatJB.requestApplyInsets(view);
1016        }
1017
1018        @Override
1019        public boolean getFitsSystemWindows(View view) {
1020            return ViewCompatJB.getFitsSystemWindows(view);
1021        }
1022    }
1023
1024    static class JbMr1ViewCompatImpl extends JBViewCompatImpl {
1025
1026        @Override
1027        public int getLabelFor(View view) {
1028            return ViewCompatJellybeanMr1.getLabelFor(view);
1029        }
1030
1031        @Override
1032        public void setLabelFor(View view, int id) {
1033            ViewCompatJellybeanMr1.setLabelFor(view, id);
1034        }
1035
1036        @Override
1037        public void setLayerPaint(View view, Paint paint) {
1038            ViewCompatJellybeanMr1.setLayerPaint(view, paint);
1039        }
1040
1041        @Override
1042        public int getLayoutDirection(View view) {
1043            return ViewCompatJellybeanMr1.getLayoutDirection(view);
1044        }
1045
1046        @Override
1047        public void setLayoutDirection(View view, int layoutDirection) {
1048            ViewCompatJellybeanMr1.setLayoutDirection(view, layoutDirection);
1049        }
1050
1051        @Override
1052        public int getPaddingStart(View view) {
1053            return ViewCompatJellybeanMr1.getPaddingStart(view);
1054        }
1055
1056        @Override
1057        public int getPaddingEnd(View view) {
1058            return ViewCompatJellybeanMr1.getPaddingEnd(view);
1059        }
1060
1061        @Override
1062        public void setPaddingRelative(View view, int start, int top, int end, int bottom) {
1063            ViewCompatJellybeanMr1.setPaddingRelative(view, start, top, end, bottom);
1064        }
1065
1066        @Override
1067        public int getWindowSystemUiVisibility(View view) {
1068            return ViewCompatJellybeanMr1.getWindowSystemUiVisibility(view);
1069        }
1070    }
1071
1072    static class KitKatViewCompatImpl extends JbMr1ViewCompatImpl {
1073        @Override
1074        public int getAccessibilityLiveRegion(View view) {
1075            return ViewCompatKitKat.getAccessibilityLiveRegion(view);
1076        }
1077
1078        @Override
1079        public void setAccessibilityLiveRegion(View view, int mode) {
1080            ViewCompatKitKat.setAccessibilityLiveRegion(view, mode);
1081        }
1082
1083        @Override
1084        public void setImportantForAccessibility(View view, int mode) {
1085            ViewCompatJB.setImportantForAccessibility(view, mode);
1086        }
1087    }
1088
1089    static class Api21ViewCompatImpl extends KitKatViewCompatImpl {
1090        @Override
1091        public void setTransitionName(View view, String transitionName) {
1092            ViewCompatApi21.setTransitionName(view, transitionName);
1093        }
1094
1095        @Override
1096        public String getTransitionName(View view) {
1097            return ViewCompatApi21.getTransitionName(view);
1098        }
1099
1100        @Override
1101        public void requestApplyInsets(View view) {
1102            ViewCompatApi21.requestApplyInsets(view);
1103        }
1104
1105        @Override
1106        public void setElevation(View view, float elevation) {
1107            ViewCompatApi21.setElevation(view, elevation);
1108        }
1109
1110        @Override
1111        public float getElevation(View view) {
1112            return ViewCompatApi21.getElevation(view);
1113        }
1114
1115        @Override
1116        public void setTranslationZ(View view, float translationZ) {
1117            ViewCompatApi21.setTranslationZ(view, translationZ);
1118        }
1119
1120        @Override
1121        public float getTranslationZ(View view) {
1122            return ViewCompatApi21.getTranslationZ(view);
1123        }
1124    }
1125
1126    static final ViewCompatImpl IMPL;
1127    static {
1128        final int version = android.os.Build.VERSION.SDK_INT;
1129        if (version >= 21) {
1130            IMPL = new Api21ViewCompatImpl();
1131        } else if (version >= 19) {
1132            IMPL = new KitKatViewCompatImpl();
1133        } else if (version >= 17) {
1134            IMPL = new JbMr1ViewCompatImpl();
1135        } else if (version >= 16) {
1136            IMPL = new JBViewCompatImpl();
1137        } else if (version >= 14) {
1138            IMPL = new ICSViewCompatImpl();
1139        } else if (version >= 11) {
1140            IMPL = new HCViewCompatImpl();
1141        } else if (version >= 9) {
1142            IMPL = new GBViewCompatImpl();
1143        } else if (version >= 7) {
1144            IMPL = new EclairMr1ViewCompatImpl();
1145        } else {
1146            IMPL = new BaseViewCompatImpl();
1147        }
1148    }
1149
1150    /**
1151     * Check if this view can be scrolled horizontally in a certain direction.
1152     *
1153     * @param v The View against which to invoke the method.
1154     * @param direction Negative to check scrolling left, positive to check scrolling right.
1155     * @return true if this view can be scrolled in the specified direction, false otherwise.
1156     */
1157    public static boolean canScrollHorizontally(View v, int direction) {
1158        return IMPL.canScrollHorizontally(v, direction);
1159    }
1160
1161    /**
1162     * Check if this view can be scrolled vertically in a certain direction.
1163     *
1164     * @param v The View against which to invoke the method.
1165     * @param direction Negative to check scrolling up, positive to check scrolling down.
1166     * @return true if this view can be scrolled in the specified direction, false otherwise.
1167     */
1168    public static boolean canScrollVertically(View v, int direction) {
1169        return IMPL.canScrollVertically(v, direction);
1170    }
1171
1172    /**
1173     * Returns the over-scroll mode for this view. The result will be
1174     * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
1175     * (allow over-scrolling only if the view content is larger than the container),
1176     * or {@link #OVER_SCROLL_NEVER}.
1177     *
1178     * @param v The View against which to invoke the method.
1179     * @return This view's over-scroll mode.
1180     */
1181    @OverScroll
1182    public static int getOverScrollMode(View v) {
1183        return IMPL.getOverScrollMode(v);
1184    }
1185
1186    /**
1187     * Set the over-scroll mode for this view. Valid over-scroll modes are
1188     * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
1189     * (allow over-scrolling only if the view content is larger than the container),
1190     * or {@link #OVER_SCROLL_NEVER}.
1191     *
1192     * Setting the over-scroll mode of a view will have an effect only if the
1193     * view is capable of scrolling.
1194     *
1195     * @param v The View against which to invoke the method.
1196     * @param overScrollMode The new over-scroll mode for this view.
1197     */
1198    public static void setOverScrollMode(View v, @OverScroll int overScrollMode) {
1199        IMPL.setOverScrollMode(v, overScrollMode);
1200    }
1201
1202    /**
1203     * Called from {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
1204     * giving a chance to this View to populate the accessibility event with its
1205     * text content. While this method is free to modify event
1206     * attributes other than text content, doing so should normally be performed in
1207     * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)}.
1208     * <p>
1209     * Example: Adding formatted date string to an accessibility event in addition
1210     *          to the text added by the super implementation:
1211     * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
1212     *     super.onPopulateAccessibilityEvent(event);
1213     *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
1214     *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
1215     *         mCurrentDate.getTimeInMillis(), flags);
1216     *     event.getText().add(selectedDateUtterance);
1217     * }</pre>
1218     * <p>
1219     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
1220     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
1221     * {@link android.view.View.AccessibilityDelegate#onPopulateAccessibilityEvent(View,
1222     *  AccessibilityEvent)}
1223     * is responsible for handling this call.
1224     * </p>
1225     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
1226     * information to the event, in case the default implementation has basic information to add.
1227     * </p>
1228     *
1229     * @param v The View against which to invoke the method.
1230     * @param event The accessibility event which to populate.
1231     *
1232     * @see View#sendAccessibilityEvent(int)
1233     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
1234     */
1235    public static void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
1236        IMPL.onPopulateAccessibilityEvent(v, event);
1237    }
1238
1239    /**
1240     * Initializes an {@link AccessibilityEvent} with information about
1241     * this View which is the event source. In other words, the source of
1242     * an accessibility event is the view whose state change triggered firing
1243     * the event.
1244     * <p>
1245     * Example: Setting the password property of an event in addition
1246     *          to properties set by the super implementation:
1247     * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
1248     *     super.onInitializeAccessibilityEvent(event);
1249     *     event.setPassword(true);
1250     * }</pre>
1251     * <p>
1252     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
1253     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
1254     * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityEvent(View,
1255     *  AccessibilityEvent)}
1256     * is responsible for handling this call.
1257     * </p>
1258     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
1259     * information to the event, in case the default implementation has basic information to add.
1260     * </p>
1261     *
1262     * @param v The View against which to invoke the method.
1263     * @param event The event to initialize.
1264     *
1265     * @see View#sendAccessibilityEvent(int)
1266     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
1267     */
1268    public static void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
1269        IMPL.onInitializeAccessibilityEvent(v, event);
1270    }
1271
1272    /**
1273     * Initializes an {@link android.view.accessibility.AccessibilityNodeInfo} with information
1274     * about this view. The base implementation sets:
1275     * <ul>
1276     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setParent(View)},</li>
1277     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInParent(Rect)},</li>
1278     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li>
1279     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setPackageName(CharSequence)},</li>
1280     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClassName(CharSequence)},</li>
1281     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setContentDescription(CharSequence)},</li>
1282     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setEnabled(boolean)},</li>
1283     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClickable(boolean)},</li>
1284     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocusable(boolean)},</li>
1285     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocused(boolean)},</li>
1286     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setLongClickable(boolean)},</li>
1287     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setSelected(boolean)},</li>
1288     * </ul>
1289     * <p>
1290     * Subclasses should override this method, call the super implementation,
1291     * and set additional attributes.
1292     * </p>
1293     * <p>
1294     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
1295     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
1296     * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View,
1297     *  android.view.accessibility.AccessibilityNodeInfo)}
1298     * is responsible for handling this call.
1299     * </p>
1300     *
1301     * @param v The View against which to invoke the method.
1302     * @param info The instance to initialize.
1303     */
1304    public static void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
1305        IMPL.onInitializeAccessibilityNodeInfo(v, info);
1306    }
1307
1308    /**
1309     * Sets a delegate for implementing accessibility support via compositon as
1310     * opposed to inheritance. The delegate's primary use is for implementing
1311     * backwards compatible widgets. For more details see
1312     * {@link android.view.View.AccessibilityDelegate}.
1313     *
1314     * @param v The View against which to invoke the method.
1315     * @param delegate The delegate instance.
1316     *
1317     * @see android.view.View.AccessibilityDelegate
1318     */
1319    public static void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
1320        IMPL.setAccessibilityDelegate(v, delegate);
1321    }
1322
1323    /**
1324     * Checks whether provided View has an accessibility delegate attached to it.
1325     *
1326     * @param v The View instance to check
1327     * @return True if the View has an accessibility delegate
1328     */
1329    public static boolean hasAccessibilityDelegate(View v) {
1330        return IMPL.hasAccessibilityDelegate(v);
1331    }
1332
1333    /**
1334     * Indicates whether the view is currently tracking transient state that the
1335     * app should not need to concern itself with saving and restoring, but that
1336     * the framework should take special note to preserve when possible.
1337     *
1338     * @param view View to check for transient state
1339     * @return true if the view has transient state
1340     */
1341    public static boolean hasTransientState(View view) {
1342        return IMPL.hasTransientState(view);
1343    }
1344
1345    /**
1346     * Set whether this view is currently tracking transient state that the
1347     * framework should attempt to preserve when possible.
1348     *
1349     * @param view View tracking transient state
1350     * @param hasTransientState true if this view has transient state
1351     */
1352    public static void setHasTransientState(View view, boolean hasTransientState) {
1353        IMPL.setHasTransientState(view, hasTransientState);
1354    }
1355
1356    /**
1357     * <p>Cause an invalidate to happen on the next animation time step, typically the
1358     * next display frame.</p>
1359     *
1360     * <p>This method can be invoked from outside of the UI thread
1361     * only when this View is attached to a window.</p>
1362     *
1363     * @param view View to invalidate
1364     */
1365    public static void postInvalidateOnAnimation(View view) {
1366        IMPL.postInvalidateOnAnimation(view);
1367    }
1368
1369    /**
1370     * <p>Cause an invalidate of the specified area to happen on the next animation
1371     * time step, typically the next display frame.</p>
1372     *
1373     * <p>This method can be invoked from outside of the UI thread
1374     * only when this View is attached to a window.</p>
1375     *
1376     * @param view View to invalidate
1377     * @param left The left coordinate of the rectangle to invalidate.
1378     * @param top The top coordinate of the rectangle to invalidate.
1379     * @param right The right coordinate of the rectangle to invalidate.
1380     * @param bottom The bottom coordinate of the rectangle to invalidate.
1381     */
1382    public static void postInvalidateOnAnimation(View view, int left, int top,
1383            int right, int bottom) {
1384        IMPL.postInvalidateOnAnimation(view, left, top, right, bottom);
1385    }
1386
1387    /**
1388     * <p>Causes the Runnable to execute on the next animation time step.
1389     * The runnable will be run on the user interface thread.</p>
1390     *
1391     * <p>This method can be invoked from outside of the UI thread
1392     * only when this View is attached to a window.</p>
1393     *
1394     * @param view View to post this Runnable to
1395     * @param action The Runnable that will be executed.
1396     */
1397    public static void postOnAnimation(View view, Runnable action) {
1398        IMPL.postOnAnimation(view, action);
1399    }
1400
1401    /**
1402     * <p>Causes the Runnable to execute on the next animation time step,
1403     * after the specified amount of time elapses.
1404     * The runnable will be run on the user interface thread.</p>
1405     *
1406     * <p>This method can be invoked from outside of the UI thread
1407     * only when this View is attached to a window.</p>
1408     *
1409     * @param view The view to post this Runnable to
1410     * @param action The Runnable that will be executed.
1411     * @param delayMillis The delay (in milliseconds) until the Runnable
1412     *        will be executed.
1413     */
1414    public static void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
1415        IMPL.postOnAnimationDelayed(view, action, delayMillis);
1416    }
1417
1418    /**
1419     * Gets the mode for determining whether this View is important for accessibility
1420     * which is if it fires accessibility events and if it is reported to
1421     * accessibility services that query the screen.
1422     *
1423     * @param view The view whose property to get.
1424     * @return The mode for determining whether a View is important for accessibility.
1425     *
1426     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
1427     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
1428     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
1429     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
1430     */
1431    @ImportantForAccessibility
1432    public static int getImportantForAccessibility(View view) {
1433        return IMPL.getImportantForAccessibility(view);
1434    }
1435
1436    /**
1437     * Sets how to determine whether this view is important for accessibility
1438     * which is if it fires accessibility events and if it is reported to
1439     * accessibility services that query the screen.
1440     * <p>
1441     * <em>Note:</em> If the current paltform version does not support the
1442     *  {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} mode, then
1443     *  {@link #IMPORTANT_FOR_ACCESSIBILITY_NO} will be used as it is the
1444     *  closest terms of semantics.
1445     * </p>
1446     *
1447     * @param view The view whose property to set.
1448     * @param mode How to determine whether this view is important for accessibility.
1449     *
1450     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
1451     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
1452     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
1453     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
1454     */
1455    public static void setImportantForAccessibility(View view,
1456            @ImportantForAccessibility int mode) {
1457        IMPL.setImportantForAccessibility(view, mode);
1458    }
1459
1460    /**
1461     * Performs the specified accessibility action on the view. For
1462     * possible accessibility actions look at {@link AccessibilityNodeInfoCompat}.
1463     * <p>
1464     * If an {@link AccessibilityDelegateCompat} has been specified via calling
1465     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
1466     * {@link AccessibilityDelegateCompat#performAccessibilityAction(View, int, Bundle)}
1467     * is responsible for handling this call.
1468     * </p>
1469     *
1470     * @param action The action to perform.
1471     * @param arguments Optional action arguments.
1472     * @return Whether the action was performed.
1473     */
1474    public static boolean performAccessibilityAction(View view, int action, Bundle arguments) {
1475        return IMPL.performAccessibilityAction(view, action, arguments);
1476    }
1477
1478    /**
1479     * Gets the provider for managing a virtual view hierarchy rooted at this View
1480     * and reported to {@link android.accessibilityservice.AccessibilityService}s
1481     * that explore the window content.
1482     * <p>
1483     * If this method returns an instance, this instance is responsible for managing
1484     * {@link AccessibilityNodeInfoCompat}s describing the virtual sub-tree rooted at
1485     * this View including the one representing the View itself. Similarly the returned
1486     * instance is responsible for performing accessibility actions on any virtual
1487     * view or the root view itself.
1488     * </p>
1489     * <p>
1490     * If an {@link AccessibilityDelegateCompat} has been specified via calling
1491     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
1492     * {@link AccessibilityDelegateCompat#getAccessibilityNodeProvider(View)}
1493     * is responsible for handling this call.
1494     * </p>
1495     *
1496     * @param view The view whose property to get.
1497     * @return The provider.
1498     *
1499     * @see AccessibilityNodeProviderCompat
1500     */
1501    public static AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
1502        return IMPL.getAccessibilityNodeProvider(view);
1503    }
1504
1505    /**
1506     * The opacity of the view. This is a value from 0 to 1, where 0 means the view is
1507     * completely transparent and 1 means the view is completely opaque.
1508     *
1509     * <p>By default this is 1.0f. Prior to API 11, the returned value is always 1.0f.
1510     * @return The opacity of the view.
1511     */
1512    public static float getAlpha(View view) {
1513        return IMPL.getAlpha(view);
1514    }
1515
1516    /**
1517     * <p>Specifies the type of layer backing this view. The layer can be
1518     * {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or
1519     * {@link #LAYER_TYPE_HARDWARE hardware}.</p>
1520     *
1521     * <p>A layer is associated with an optional {@link android.graphics.Paint}
1522     * instance that controls how the layer is composed on screen. The following
1523     * properties of the paint are taken into account when composing the layer:</p>
1524     * <ul>
1525     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
1526     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
1527     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
1528     * </ul>
1529     *
1530     * <p>If this view has an alpha value set to < 1.0 by calling
1531     * setAlpha(float), the alpha value of the layer's paint is replaced by
1532     * this view's alpha value. Calling setAlpha(float) is therefore
1533     * equivalent to setting a hardware layer on this view and providing a paint with
1534     * the desired alpha value.<p>
1535     *
1536     * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled},
1537     * {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware}
1538     * for more information on when and how to use layers.</p>
1539     *
1540     * @param layerType The ype of layer to use with this view, must be one of
1541     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
1542     *        {@link #LAYER_TYPE_HARDWARE}
1543     * @param paint The paint used to compose the layer. This argument is optional
1544     *        and can be null. It is ignored when the layer type is
1545     *        {@link #LAYER_TYPE_NONE}
1546     *
1547     * @param view View to set the layer type for
1548     * @param layerType The type of layer to use with this view, must be one of
1549     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
1550     *        {@link #LAYER_TYPE_HARDWARE}
1551     * @param paint The paint used to compose the layer. This argument is optional
1552     *        and can be null. It is ignored when the layer type is
1553     *        {@link #LAYER_TYPE_NONE}
1554     */
1555    public static void setLayerType(View view, @LayerType int layerType, Paint paint) {
1556        IMPL.setLayerType(view, layerType, paint);
1557    }
1558
1559    /**
1560     * Indicates what type of layer is currently associated with this view. By default
1561     * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
1562     * Refer to the documentation of
1563     * {@link #setLayerType(android.view.View, int, android.graphics.Paint)}
1564     * for more information on the different types of layers.
1565     *
1566     * @param view The view to fetch the layer type from
1567     * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
1568     *         {@link #LAYER_TYPE_HARDWARE}
1569     *
1570     * @see #setLayerType(android.view.View, int, android.graphics.Paint)
1571     * @see #LAYER_TYPE_NONE
1572     * @see #LAYER_TYPE_SOFTWARE
1573     * @see #LAYER_TYPE_HARDWARE
1574     */
1575    @LayerType
1576    public static int getLayerType(View view) {
1577        return IMPL.getLayerType(view);
1578    }
1579
1580    /**
1581     * Gets the id of a view for which a given view serves as a label for
1582     * accessibility purposes.
1583     *
1584     * @param view The view on which to invoke the corresponding method.
1585     * @return The labeled view id.
1586     */
1587    public static int getLabelFor(View view) {
1588        return IMPL.getLabelFor(view);
1589    }
1590
1591    /**
1592     * Sets the id of a view for which a given view serves as a label for
1593     * accessibility purposes.
1594     *
1595     * @param view The view on which to invoke the corresponding method.
1596     * @param labeledId The labeled view id.
1597     */
1598    public static void setLabelFor(View view, @IdRes int labeledId) {
1599        IMPL.setLabelFor(view, labeledId);
1600    }
1601
1602    /**
1603     * Updates the {@link Paint} object used with the current layer (used only if the current
1604     * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
1605     * provided to {@link #setLayerType(android.view.View, int, android.graphics.Paint)}
1606     * will be used the next time the View is redrawn, but
1607     * {@link #setLayerPaint(android.view.View, android.graphics.Paint)}
1608     * must be called to ensure that the view gets redrawn immediately.
1609     *
1610     * <p>A layer is associated with an optional {@link android.graphics.Paint}
1611     * instance that controls how the layer is composed on screen. The following
1612     * properties of the paint are taken into account when composing the layer:</p>
1613     * <ul>
1614     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
1615     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
1616     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
1617     * </ul>
1618     *
1619     * <p>If this view has an alpha value set to < 1.0 by calling
1620     * View#setAlpha(float), the alpha value of the layer's paint is replaced by
1621     * this view's alpha value. Calling View#setAlpha(float) is therefore
1622     * equivalent to setting a hardware layer on this view and providing a paint with
1623     * the desired alpha value.</p>
1624     *
1625     * @param view View to set a layer paint for
1626     * @param paint The paint used to compose the layer. This argument is optional
1627     *        and can be null. It is ignored when the layer type is
1628     *        {@link #LAYER_TYPE_NONE}
1629     *
1630     * @see #setLayerType(View, int, android.graphics.Paint)
1631     */
1632    public static void setLayerPaint(View view, Paint paint) {
1633        IMPL.setLayerPaint(view, paint);
1634    }
1635
1636    /**
1637     * Returns the resolved layout direction for this view.
1638     *
1639     * @param view View to get layout direction for
1640     * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
1641     * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
1642     *
1643     * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version
1644     * is lower than Jellybean MR1 (API 17)
1645     */
1646    @ResolvedLayoutDirectionMode
1647    public static int getLayoutDirection(View view) {
1648        return IMPL.getLayoutDirection(view);
1649    }
1650
1651    /**
1652     * Set the layout direction for this view. This will propagate a reset of layout direction
1653     * resolution to the view's children and resolve layout direction for this view.
1654     *
1655     * @param view View to set layout direction for
1656     * @param layoutDirection the layout direction to set. Should be one of:
1657     *
1658     * {@link #LAYOUT_DIRECTION_LTR},
1659     * {@link #LAYOUT_DIRECTION_RTL},
1660     * {@link #LAYOUT_DIRECTION_INHERIT},
1661     * {@link #LAYOUT_DIRECTION_LOCALE}.
1662     *
1663     * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution
1664     * proceeds up the parent chain of the view to get the value. If there is no parent, then it
1665     * will return the default {@link #LAYOUT_DIRECTION_LTR}.
1666     */
1667    public static void setLayoutDirection(View view, @LayoutDirectionMode int layoutDirection) {
1668        IMPL.setLayoutDirection(view, layoutDirection);
1669    }
1670
1671    /**
1672     * Gets the parent for accessibility purposes. Note that the parent for
1673     * accessibility is not necessary the immediate parent. It is the first
1674     * predecessor that is important for accessibility.
1675     *
1676     * @param view View to retrieve parent for
1677     * @return The parent for use in accessibility inspection
1678     */
1679    public static ViewParent getParentForAccessibility(View view) {
1680        return IMPL.getParentForAccessibility(view);
1681    }
1682
1683    /**
1684     * Indicates whether this View is opaque. An opaque View guarantees that it will
1685     * draw all the pixels overlapping its bounds using a fully opaque color.
1686     *
1687     * On API 7 and above this will call View's true isOpaque method. On previous platform
1688     * versions it will check the opacity of the view's background drawable if present.
1689     *
1690     * @return True if this View is guaranteed to be fully opaque, false otherwise.
1691     */
1692    public static boolean isOpaque(View view) {
1693        return IMPL.isOpaque(view);
1694    }
1695
1696    /**
1697     * Utility to reconcile a desired size and state, with constraints imposed
1698     * by a MeasureSpec.  Will take the desired size, unless a different size
1699     * is imposed by the constraints.  The returned value is a compound integer,
1700     * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
1701     * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting
1702     * size is smaller than the size the view wants to be.
1703     *
1704     * @param size How big the view wants to be
1705     * @param measureSpec Constraints imposed by the parent
1706     * @return Size information bit mask as defined by
1707     * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
1708     */
1709    public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
1710        return IMPL.resolveSizeAndState(size, measureSpec, childMeasuredState);
1711    }
1712
1713    /**
1714     * Return the full width measurement information for this view as computed
1715     * by the most recent call to {@link android.view.View#measure(int, int)}.
1716     * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and
1717     * {@link #MEASURED_STATE_TOO_SMALL}.
1718     * This should be used during measurement and layout calculations only. Use
1719     * {@link android.view.View#getWidth()} to see how wide a view is after layout.
1720     *
1721     * @return The measured width of this view as a bit mask.
1722     */
1723    public static int getMeasuredWidthAndState(View view) {
1724        return IMPL.getMeasuredWidthAndState(view);
1725    }
1726
1727    /**
1728     * Return the full height measurement information for this view as computed
1729     * by the most recent call to {@link android.view.View#measure(int, int)}.
1730     * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and
1731     * {@link #MEASURED_STATE_TOO_SMALL}.
1732     * This should be used during measurement and layout calculations only. Use
1733     * {@link android.view.View#getHeight()} to see how wide a view is after layout.
1734     *
1735     * @return The measured width of this view as a bit mask.
1736     */
1737    public static int getMeasuredHeightAndState(View view) {
1738        return IMPL.getMeasuredHeightAndState(view);
1739    }
1740
1741    /**
1742     * Return only the state bits of {@link #getMeasuredWidthAndState}
1743     * and {@link #getMeasuredHeightAndState}, combined into one integer.
1744     * The width component is in the regular bits {@link #MEASURED_STATE_MASK}
1745     * and the height component is at the shifted bits
1746     * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}.
1747     */
1748    public static int getMeasuredState(View view) {
1749        return IMPL.getMeasuredState(view);
1750    }
1751
1752    /**
1753     * Gets the live region mode for the specified View.
1754     *
1755     * @param view The view from which to obtain the live region mode
1756     * @return The live region mode for the view.
1757     *
1758     * @see ViewCompat#setAccessibilityLiveRegion(View, int)
1759     */
1760    @AccessibilityLiveRegion
1761    public static int getAccessibilityLiveRegion(View view) {
1762        return IMPL.getAccessibilityLiveRegion(view);
1763    }
1764
1765    /**
1766     * Sets the live region mode for the specified view. This indicates to
1767     * accessibility services whether they should automatically notify the user
1768     * about changes to the view's content description or text, or to the
1769     * content descriptions or text of the view's children (where applicable).
1770     * <p>
1771     * For example, in a login screen with a TextView that displays an "incorrect
1772     * password" notification, that view should be marked as a live region with
1773     * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
1774     * <p>
1775     * To disable change notifications for this view, use
1776     * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
1777     * mode for most views.
1778     * <p>
1779     * To indicate that the user should be notified of changes, use
1780     * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
1781     * <p>
1782     * If the view's changes should interrupt ongoing speech and notify the user
1783     * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}.
1784     *
1785     * @param view The view on which to set the live region mode
1786     * @param mode The live region mode for this view, one of:
1787     *        <ul>
1788     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE}
1789     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE}
1790     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
1791     *        </ul>
1792     */
1793    public static void setAccessibilityLiveRegion(View view, @AccessibilityLiveRegion int mode) {
1794        IMPL.setAccessibilityLiveRegion(view, mode);
1795    }
1796
1797    /**
1798     * Returns the start padding of the specified view depending on its resolved layout direction.
1799     * If there are inset and enabled scrollbars, this value may include the space
1800     * required to display the scrollbars as well.
1801     *
1802     * @param view The view to get padding for
1803     * @return the start padding in pixels
1804     */
1805    public static int getPaddingStart(View view) {
1806        return IMPL.getPaddingStart(view);
1807    }
1808
1809    /**
1810     * Returns the end padding of the specified view depending on its resolved layout direction.
1811     * If there are inset and enabled scrollbars, this value may include the space
1812     * required to display the scrollbars as well.
1813     *
1814     * @param view The view to get padding for
1815     * @return the end padding in pixels
1816     */
1817    public static int getPaddingEnd(View view) {
1818        return IMPL.getPaddingEnd(view);
1819    }
1820
1821    /**
1822     * Sets the relative padding. The view may add on the space required to display
1823     * the scrollbars, depending on the style and visibility of the scrollbars.
1824     * So the values returned from {@link #getPaddingStart}, {@link View#getPaddingTop},
1825     * {@link #getPaddingEnd} and {@link View#getPaddingBottom} may be different
1826     * from the values set in this call.
1827     *
1828     * @param view The view on which to set relative padding
1829     * @param start the start padding in pixels
1830     * @param top the top padding in pixels
1831     * @param end the end padding in pixels
1832     * @param bottom the bottom padding in pixels
1833     */
1834    public static void setPaddingRelative(View view, int start, int top, int end, int bottom) {
1835        IMPL.setPaddingRelative(view, start, top, end, bottom);
1836    }
1837
1838    /**
1839     * Notify a view that it is being temporarily detached.
1840     */
1841    public static void dispatchStartTemporaryDetach(View view) {
1842        IMPL.dispatchStartTemporaryDetach(view);
1843    }
1844
1845    /**
1846     * Notify a view that its temporary detach has ended; the view is now reattached.
1847     */
1848    public static void dispatchFinishTemporaryDetach(View view) {
1849        IMPL.dispatchFinishTemporaryDetach(view);
1850    }
1851
1852    /**
1853     * The horizontal location of this view relative to its {@link View#getLeft() left} position.
1854     * This position is post-layout, in addition to wherever the object's
1855     * layout placed it.
1856     *
1857     * <p>Prior to API 11 this will return 0.</p>
1858     *
1859     * @return The horizontal position of this view relative to its left position, in pixels.
1860     */
1861    public static float getTranslationX(View view) {
1862        return IMPL.getTranslationX(view);
1863    }
1864
1865    /**
1866     * The vertical location of this view relative to its {@link View#getTop() left} position.
1867     * This position is post-layout, in addition to wherever the object's
1868     * layout placed it.
1869     *
1870     * <p>Prior to API 11 this will return 0.</p>
1871     *
1872     * @return The vertical position of this view relative to its top position, in pixels.
1873     */
1874    public static float getTranslationY(View view) {
1875        return IMPL.getTranslationY(view);
1876    }
1877
1878    /**
1879     * Returns the minimum width of the view.
1880     *
1881     * <p>Prior to API 16 this will return 0.</p>
1882     *
1883     * @return the minimum width the view will try to be.
1884     */
1885    public static int getMinimumWidth(View view) {
1886        return IMPL.getMinimumWidth(view);
1887    }
1888
1889    /**
1890     * Returns the minimum height of the view.
1891     *
1892     * <p>Prior to API 16 this will return 0.</p>
1893     *
1894     * @return the minimum height the view will try to be.
1895     */
1896    public static int getMinimumHeight(View view) {
1897        return IMPL.getMinimumHeight(view);
1898    }
1899
1900    /**
1901     * This method returns a ViewPropertyAnimator object, which can be used to animate
1902     * specific properties on this View.
1903     *
1904     * <p>Prior to API 14, this method will do nothing.</p>
1905     *
1906     * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
1907     */
1908    public static ViewPropertyAnimatorCompat animate(View view) {
1909        return IMPL.animate(view);
1910    }
1911
1912    /**
1913     * Sets the horizontal location of this view relative to its left position.
1914     * This effectively positions the object post-layout, in addition to wherever the object's
1915     * layout placed it.
1916     *
1917     * <p>Prior to API 11 this will have no effect.</p>
1918     *
1919     * @param value The horizontal position of this view relative to its left position,
1920     * in pixels.
1921     */
1922    public static void setTranslationX(View view, float value) {
1923        IMPL.setTranslationX(view, value);
1924    }
1925
1926    /**
1927     * Sets the vertical location of this view relative to its top position.
1928     * This effectively positions the object post-layout, in addition to wherever the object's
1929     * layout placed it.
1930     *
1931     * <p>Prior to API 11 this will have no effect.</p>
1932     *
1933     * @param value The vertical position of this view relative to its top position,
1934     * in pixels.
1935     *
1936     * @attr ref android.R.styleable#View_translationY
1937     */
1938    public static void setTranslationY(View view, float value) {
1939        IMPL.setTranslationY(view, value);
1940    }
1941
1942    /**
1943     * <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
1944     * completely transparent and 1 means the view is completely opaque.</p>
1945     *
1946     * <p> Note that setting alpha to a translucent value (0 < alpha < 1) can have significant
1947     * performance implications, especially for large views. It is best to use the alpha property
1948     * sparingly and transiently, as in the case of fading animations.</p>
1949     *
1950     * <p>Prior to API 11 this will have no effect.</p>
1951     *
1952     * @param value The opacity of the view.
1953     */
1954    public static void setAlpha(View view, float value) {
1955        IMPL.setAlpha(view, value);
1956    }
1957
1958    /**
1959     * Sets the visual x position of this view, in pixels. This is equivalent to setting the
1960     * {@link #setTranslationX(View, float) translationX} property to be the difference between
1961     * the x value passed in and the current left property of the view as determined
1962     * by the layout bounds.
1963     *
1964     * <p>Prior to API 11 this will have no effect.</p>
1965     *
1966     * @param value The visual x position of this view, in pixels.
1967     */
1968    public static void setX(View view, float value) {
1969        IMPL.setX(view, value);
1970    }
1971
1972    /**
1973     * Sets the visual y position of this view, in pixels. This is equivalent to setting the
1974     * {@link #setTranslationY(View, float) translationY} property to be the difference between
1975     * the y value passed in and the current top property of the view as determined by the
1976     * layout bounds.
1977     *
1978     * <p>Prior to API 11 this will have no effect.</p>
1979     *
1980     * @param value The visual y position of this view, in pixels.
1981     */
1982    public static void setY(View view, float value) {
1983        IMPL.setY(view, value);
1984    }
1985
1986    /**
1987     * Sets the degrees that the view is rotated around the pivot point. Increasing values
1988     * result in clockwise rotation.
1989     *
1990     * <p>Prior to API 11 this will have no effect.</p>
1991     *
1992     * @param value The degrees of rotation.
1993     */
1994    public static void setRotation(View view, float value) {
1995        IMPL.setRotation(view, value);
1996    }
1997
1998    /**
1999     * Sets the degrees that the view is rotated around the horizontal axis through the pivot point.
2000     * Increasing values result in clockwise rotation from the viewpoint of looking down the
2001     * x axis.
2002     *
2003     * <p>Prior to API 11 this will have no effect.</p>
2004     *
2005     * @param value The degrees of X rotation.
2006     */
2007    public static void setRotationX(View view, float value) {
2008        IMPL.setRotationX(view, value);
2009    }
2010
2011    /**
2012     * Sets the degrees that the view is rotated around the vertical axis through the pivot point.
2013     * Increasing values result in counter-clockwise rotation from the viewpoint of looking
2014     * down the y axis.
2015     *
2016     * <p>Prior to API 11 this will have no effect.</p>
2017     *
2018     * @param value The degrees of Y rotation.
2019     */
2020    public static void setRotationY(View view, float value) {
2021        IMPL.setRotationY(view, value);
2022    }
2023
2024    /**
2025     * Sets the amount that the view is scaled in x around the pivot point, as a proportion of
2026     * the view's unscaled width. A value of 1 means that no scaling is applied.
2027     *
2028     * <p>Prior to API 11 this will have no effect.</p>
2029     *
2030     * @param value The scaling factor.
2031     */
2032    public static void setScaleX(View view, float value) {
2033        IMPL.setScaleX(view, value);
2034    }
2035
2036    /**
2037     * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of
2038     * the view's unscaled width. A value of 1 means that no scaling is applied.
2039     *
2040     * <p>Prior to API 11 this will have no effect.</p>
2041     *
2042     * @param value The scaling factor.
2043     */
2044    public static void setScaleY(View view, float value) {
2045        IMPL.setScaleY(view, value);
2046    }
2047
2048    /**
2049     * The x location of the point around which the view is
2050     * {@link #setRotation(View, float) rotated} and {@link #setScaleX(View, float) scaled}.
2051     *
2052     * <p>Prior to API 11 this will have no effect.</p>
2053     *
2054     */
2055    public static float getPivotX(View view) {
2056        return IMPL.getPivotX(view);
2057    }
2058
2059    /**
2060     * Sets the x location of the point around which the view is
2061     * {@link #setRotation(View, float) rotated} and {@link #setScaleX(View, float) scaled}.
2062     * By default, the pivot point is centered on the object.
2063     * Setting this property disables this behavior and causes the view to use only the
2064     * explicitly set pivotX and pivotY values.
2065     *
2066     * <p>Prior to API 11 this will have no effect.</p>
2067     *
2068     * @param value The x location of the pivot point.
2069     */
2070    public static void setPivotX(View view, float value) {
2071        IMPL.setPivotX(view, value);
2072    }
2073
2074    /**
2075     * The y location of the point around which the view is {@link #setRotation(View,
2076     * float) rotated} and {@link #setScaleY(View, float) scaled}.
2077     *
2078     * <p>Prior to API 11 this will return 0.</p>
2079     *
2080     * @return The y location of the pivot point.
2081     */
2082    public static float getPivotY(View view) {
2083        return IMPL.getPivotY(view);
2084    }
2085
2086    /**
2087     * Sets the y location of the point around which the view is
2088     * {@link #setRotation(View, float) rotated} and {@link #setScaleY(View, float) scaled}.
2089     * By default, the pivot point is centered on the object.
2090     * Setting this property disables this behavior and causes the view to use only the
2091     * explicitly set pivotX and pivotY values.
2092     *
2093     * <p>Prior to API 11 this will have no effect.</p>
2094     *
2095     * @param value The y location of the pivot point.
2096     */
2097    public static void setPivotY(View view, float value) {
2098        IMPL.setPivotX(view, value);
2099    }
2100
2101    public static float getRotation(View view) {
2102        return IMPL.getRotation(view);
2103    }
2104
2105    public static float getRotationX(View view) {
2106        return IMPL.getRotationX(view);
2107    }
2108
2109    public static float getRotationY(View view) {
2110        return IMPL.getRotationY(view);
2111    }
2112
2113    public static float getScaleX(View view) {
2114        return IMPL.getScaleX(view);
2115    }
2116
2117    public static float getScaleY(View view) {
2118        return IMPL.getScaleY(view);
2119    }
2120
2121    public static float getX(View view) {
2122        return IMPL.getX(view);
2123    }
2124
2125    public static float getY(View view) {
2126        return IMPL.getY(view);
2127    }
2128
2129    /**
2130     * Sets the base elevation of this view, in pixels.
2131     */
2132    public static void setElevation(View view, float elevation) {
2133        IMPL.setElevation(view, elevation);
2134    }
2135
2136    /**
2137     * The base elevation of this view relative to its parent, in pixels.
2138     *
2139     * @return The base depth position of the view, in pixels.
2140     */
2141    public static float getElevation(View view) {
2142        return IMPL.getElevation(view);
2143    }
2144
2145    /**
2146     * Sets the depth location of this view relative to its {@link #getElevation(View) elevation}.
2147     */
2148    public static void setTranslationZ(View view, float translationZ) {
2149        IMPL.setTranslationZ(view, translationZ);
2150    }
2151
2152    /**
2153     * The depth location of this view relative to its {@link #getElevation(View) elevation}.
2154     *
2155     * @return The depth of this view relative to its elevation.
2156     */
2157    public static float getTranslationZ(View view) {
2158        return IMPL.getTranslationZ(view);
2159    }
2160
2161    /**
2162     * Sets the name of the View to be used to identify Views in Transitions.
2163     * Names should be unique in the View hierarchy.
2164     *
2165     * @param view The View against which to invoke the method.
2166     * @param transitionName The name of the View to uniquely identify it for Transitions.
2167     */
2168    public static void setTransitionName(View view, String transitionName) {
2169        IMPL.setTransitionName(view, transitionName);
2170    }
2171
2172    /**
2173     * Returns the name of the View to be used to identify Views in Transitions.
2174     * Names should be unique in the View hierarchy.
2175     *
2176     * <p>This returns null if the View has not been given a name.</p>
2177     *
2178     * @param view The View against which to invoke the method.
2179     * @return The name used of the View to be used to identify Views in Transitions or null
2180     * if no name has been given.
2181     */
2182    public static String getTransitionName(View view) {
2183        return IMPL.getTransitionName(view);
2184    }
2185
2186    /**
2187     * Returns the current system UI visibility that is currently set for the entire window.
2188     */
2189    public static int getWindowSystemUiVisibility(View view) {
2190        return IMPL.getWindowSystemUiVisibility(view);
2191    }
2192
2193    /**
2194     * Ask that a new dispatch of {@code View.onApplyWindowInsets(WindowInsets)} be performed. This
2195     * falls back to {@code View.requestFitSystemWindows()} where available.
2196     */
2197    public static void requestApplyInsets(View view) {
2198        IMPL.requestApplyInsets(view);
2199    }
2200
2201    /**
2202     * Tells the ViewGroup whether to draw its children in the order defined by the method
2203     * {@code ViewGroup.getChildDrawingOrder(int, int)}.
2204     *
2205     * @param enabled true if the order of the children when drawing is determined by
2206     *        {@link ViewGroup#getChildDrawingOrder(int, int)}, false otherwise
2207     *
2208     * <p>Prior to API 7 this will have no effect.</p>
2209     */
2210    public static void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) {
2211       IMPL.setChildrenDrawingOrderEnabled(viewGroup, enabled);
2212    }
2213
2214    /**
2215     * Returns true if this view should adapt to fit system window insets. This method will always
2216     * return false before API 16 (Jellybean).
2217     */
2218    public static boolean getFitsSystemWindows(View v) {
2219        return IMPL.getFitsSystemWindows(v);
2220    }
2221
2222    // TODO: getters for various view properties (rotation, etc)
2223}
2224