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