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