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