ViewCompat.java revision b12ba0547b2fad1c4dfc12dec36c5e7893974e67
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.v4.view.accessibility.AccessibilityNodeInfoCompat;
25import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
26import android.view.View;
27import android.view.ViewParent;
28import android.view.accessibility.AccessibilityEvent;
29
30/**
31 * Helper for accessing features in {@link View} introduced after API
32 * level 4 in a backwards compatible fashion.
33 */
34public class ViewCompat {
35    /**
36     * Always allow a user to over-scroll this view, provided it is a
37     * view that can scroll.
38     */
39    public static final int OVER_SCROLL_ALWAYS = 0;
40
41    /**
42     * Allow a user to over-scroll this view only if the content is large
43     * enough to meaningfully scroll, provided it is a view that can scroll.
44     */
45    public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1;
46
47    /**
48     * Never allow a user to over-scroll this view.
49     */
50    public static final int OVER_SCROLL_NEVER = 2;
51
52    private static final long FAKE_FRAME_TIME = 10;
53
54    /**
55     * Automatically determine whether a view is important for accessibility.
56     */
57    public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000;
58
59    /**
60     * The view is important for accessibility.
61     */
62    public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001;
63
64    /**
65     * The view is not important for accessibility.
66     */
67    public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002;
68
69    /**
70     * Indicates that the view does not have a layer.
71     */
72    public static final int LAYER_TYPE_NONE = 0;
73
74    /**
75     * <p>Indicates that the view has a software layer. A software layer is backed
76     * by a bitmap and causes the view to be rendered using Android's software
77     * rendering pipeline, even if hardware acceleration is enabled.</p>
78     *
79     * <p>Software layers have various usages:</p>
80     * <p>When the application is not using hardware acceleration, a software layer
81     * is useful to apply a specific color filter and/or blending mode and/or
82     * translucency to a view and all its children.</p>
83     * <p>When the application is using hardware acceleration, a software layer
84     * is useful to render drawing primitives not supported by the hardware
85     * accelerated pipeline. It can also be used to cache a complex view tree
86     * into a texture and reduce the complexity of drawing operations. For instance,
87     * when animating a complex view tree with a translation, a software layer can
88     * be used to render the view tree only once.</p>
89     * <p>Software layers should be avoided when the affected view tree updates
90     * often. Every update will require to re-render the software layer, which can
91     * potentially be slow (particularly when hardware acceleration is turned on
92     * since the layer will have to be uploaded into a hardware texture after every
93     * update.)</p>
94     */
95    public static final int LAYER_TYPE_SOFTWARE = 1;
96
97    /**
98     * <p>Indicates that the view has a hardware layer. A hardware layer is backed
99     * by a hardware specific texture (generally Frame Buffer Objects or FBO on
100     * OpenGL hardware) and causes the view to be rendered using Android's hardware
101     * rendering pipeline, but only if hardware acceleration is turned on for the
102     * view hierarchy. When hardware acceleration is turned off, hardware layers
103     * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
104     *
105     * <p>A hardware layer is useful to apply a specific color filter and/or
106     * blending mode and/or translucency to a view and all its children.</p>
107     * <p>A hardware layer can be used to cache a complex view tree into a
108     * texture and reduce the complexity of drawing operations. For instance,
109     * when animating a complex view tree with a translation, a hardware layer can
110     * be used to render the view tree only once.</p>
111     * <p>A hardware layer can also be used to increase the rendering quality when
112     * rotation transformations are applied on a view. It can also be used to
113     * prevent potential clipping issues when applying 3D transforms on a view.</p>
114     */
115    public static final int LAYER_TYPE_HARDWARE = 2;
116
117    /**
118     * Horizontal layout direction of this view is from Left to Right.
119     */
120    public static final int LAYOUT_DIRECTION_LTR = 0;
121
122    /**
123     * Horizontal layout direction of this view is from Right to Left.
124     */
125    public static final int LAYOUT_DIRECTION_RTL = 1;
126
127    /**
128     * Horizontal layout direction of this view is inherited from its parent.
129     * Use with {@link #setLayoutDirection}.
130     */
131    public static final int LAYOUT_DIRECTION_INHERIT = 2;
132
133    /**
134     * Horizontal layout direction of this view is from deduced from the default language
135     * script for the locale. Use with {@link #setLayoutDirection}.
136     */
137    public static final int LAYOUT_DIRECTION_LOCALE = 3;
138
139    /**
140     * Bits of {@link #getMeasuredWidthAndState} and
141     * {@link #getMeasuredWidthAndState} that provide the actual measured size.
142     */
143    public static final int MEASURED_SIZE_MASK = 0x00ffffff;
144
145    /**
146     * Bits of {@link #getMeasuredWidthAndState} and
147     * {@link #getMeasuredWidthAndState} that provide the additional state bits.
148     */
149    public static final int MEASURED_STATE_MASK = 0xff000000;
150
151    /**
152     * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits
153     * for functions that combine both width and height into a single int,
154     * such as {@link #getMeasuredState} and the childState argument of
155     * {@link #resolveSizeAndState(int, int, int)}.
156     */
157    public static final int MEASURED_HEIGHT_STATE_SHIFT = 16;
158
159    /**
160     * Bit of {@link #getMeasuredWidthAndState} and
161     * {@link #getMeasuredWidthAndState} that indicates the measured size
162     * is smaller that the space the view would like to have.
163     */
164    public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
165
166    interface ViewCompatImpl {
167        public boolean canScrollHorizontally(View v, int direction);
168        public boolean canScrollVertically(View v, int direction);
169        public int getOverScrollMode(View v);
170        public void setOverScrollMode(View v, int mode);
171        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event);
172        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event);
173        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info);
174        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate);
175        public boolean hasTransientState(View view);
176        public void setHasTransientState(View view, boolean hasTransientState);
177        public void postInvalidateOnAnimation(View view);
178        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom);
179        public void postOnAnimation(View view, Runnable action);
180        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis);
181        public int getImportantForAccessibility(View view);
182        public void setImportantForAccessibility(View view, int mode);
183        public boolean performAccessibilityAction(View view, int action, Bundle arguments);
184        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view);
185        public float getAlpha(View view);
186        public void setLayerType(View view, int layerType, Paint paint);
187        public int getLayerType(View view);
188        public int getLabelFor(View view);
189        public void setLabelFor(View view, int id);
190        public void setLayerPaint(View view, Paint paint);
191        public int getLayoutDirection(View view);
192        public void setLayoutDirection(View view, int layoutDirection);
193        public ViewParent getParentForAccessibility(View view);
194        public boolean isOpaque(View view);
195        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState);
196        public int getMeasuredWidthAndState(View view);
197        public int getMeasuredHeightAndState(View view);
198        public int getMeasuredState(View view);
199    }
200
201    static class BaseViewCompatImpl implements ViewCompatImpl {
202        public boolean canScrollHorizontally(View v, int direction) {
203            return false;
204        }
205        public boolean canScrollVertically(View v, int direction) {
206            return false;
207        }
208        public int getOverScrollMode(View v) {
209            return OVER_SCROLL_NEVER;
210        }
211        public void setOverScrollMode(View v, int mode) {
212            // Do nothing; API doesn't exist
213        }
214        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
215            // Do nothing; API doesn't exist
216        }
217        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
218            // Do nothing; API doesn't exist
219        }
220        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
221         // Do nothing; API doesn't exist
222        }
223        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
224            // Do nothing; API doesn't exist
225        }
226        public boolean hasTransientState(View view) {
227            // A view can't have transient state if transient state wasn't supported.
228            return false;
229        }
230        public void setHasTransientState(View view, boolean hasTransientState) {
231            // Do nothing; API doesn't exist
232        }
233        public void postInvalidateOnAnimation(View view) {
234            view.postInvalidateDelayed(getFrameTime());
235        }
236        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) {
237            view.postInvalidateDelayed(getFrameTime(), left, top, right, bottom);
238        }
239        public void postOnAnimation(View view, Runnable action) {
240            view.postDelayed(action, getFrameTime());
241        }
242        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
243            view.postDelayed(action, getFrameTime() + delayMillis);
244        }
245        long getFrameTime() {
246            return FAKE_FRAME_TIME;
247        }
248        public int getImportantForAccessibility(View view) {
249            return 0;
250        }
251        public void setImportantForAccessibility(View view, int mode) {
252
253        }
254        public boolean performAccessibilityAction(View view, int action, Bundle arguments) {
255            return false;
256        }
257        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
258            return null;
259        }
260        public float getAlpha(View view) {
261            return 1.0f;
262        }
263        public void setLayerType(View view, int layerType, Paint paint) {
264            // No-op until layers became available (HC)
265        }
266        public int getLayerType(View view) {
267            return LAYER_TYPE_NONE;
268        }
269        public int getLabelFor(View view) {
270            return 0;
271        }
272        public void setLabelFor(View view, int id) {
273
274        }
275        public void setLayerPaint(View view, Paint p) {
276            // No-op until layers became available (HC)
277        }
278
279        @Override
280        public int getLayoutDirection(View view) {
281            return LAYOUT_DIRECTION_LTR;
282        }
283
284        @Override
285        public void setLayoutDirection(View view, int layoutDirection) {
286            // No-op
287        }
288
289        @Override
290        public ViewParent getParentForAccessibility(View view) {
291            return view.getParent();
292        }
293
294        @Override
295        public boolean isOpaque(View view) {
296            final Drawable bg = view.getBackground();
297            if (bg != null) {
298                return bg.getOpacity() == PixelFormat.OPAQUE;
299            }
300            return false;
301        }
302
303        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
304            return View.resolveSize(size, measureSpec);
305        }
306
307        @Override
308        public int getMeasuredWidthAndState(View view) {
309            return view.getMeasuredWidth();
310        }
311
312        @Override
313        public int getMeasuredHeightAndState(View view) {
314            return view.getMeasuredHeight();
315        }
316
317        @Override
318        public int getMeasuredState(View view) {
319            return 0;
320        }
321    }
322
323    static class EclairMr1ViewCompatImpl extends BaseViewCompatImpl {
324        @Override
325        public boolean isOpaque(View view) {
326            return ViewCompatEclairMr1.isOpaque(view);
327        }
328    }
329
330    static class GBViewCompatImpl extends EclairMr1ViewCompatImpl {
331        @Override
332        public int getOverScrollMode(View v) {
333            return ViewCompatGingerbread.getOverScrollMode(v);
334        }
335        @Override
336        public void setOverScrollMode(View v, int mode) {
337            ViewCompatGingerbread.setOverScrollMode(v, mode);
338        }
339    }
340
341    static class HCViewCompatImpl extends GBViewCompatImpl {
342        @Override
343        long getFrameTime() {
344            return ViewCompatHC.getFrameTime();
345        }
346        @Override
347        public float getAlpha(View view) {
348            return ViewCompatHC.getAlpha(view);
349        }
350        @Override
351        public void setLayerType(View view, int layerType, Paint paint) {
352            ViewCompatHC.setLayerType(view, layerType, paint);
353        }
354        @Override
355        public int getLayerType(View view)  {
356            return ViewCompatHC.getLayerType(view);
357        }
358        @Override
359        public void setLayerPaint(View view, Paint paint) {
360            // Make sure the paint is correct; this will be cheap if it's the same
361            // instance as was used to call setLayerType earlier.
362            setLayerType(view, getLayerType(view), paint);
363            // This is expensive, but the only way to accomplish this before JB-MR1.
364            view.invalidate();
365        }
366        @Override
367        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
368            return ViewCompatHC.resolveSizeAndState(size, measureSpec, childMeasuredState);
369        }
370        @Override
371        public int getMeasuredWidthAndState(View view) {
372            return ViewCompatHC.getMeasuredWidthAndState(view);
373        }
374        @Override
375        public int getMeasuredHeightAndState(View view) {
376            return ViewCompatHC.getMeasuredHeightAndState(view);
377        }
378        @Override
379        public int getMeasuredState(View view) {
380            return ViewCompatHC.getMeasuredState(view);
381        }
382    }
383
384    static class ICSViewCompatImpl extends HCViewCompatImpl {
385        @Override
386        public boolean canScrollHorizontally(View v, int direction) {
387            return ViewCompatICS.canScrollHorizontally(v, direction);
388        }
389        @Override
390        public boolean canScrollVertically(View v, int direction) {
391            return ViewCompatICS.canScrollVertically(v, direction);
392        }
393        @Override
394        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
395            ViewCompatICS.onPopulateAccessibilityEvent(v, event);
396        }
397        @Override
398        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
399            ViewCompatICS.onInitializeAccessibilityEvent(v, event);
400        }
401        @Override
402        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
403            ViewCompatICS.onInitializeAccessibilityNodeInfo(v, info.getInfo());
404        }
405        @Override
406        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
407            ViewCompatICS.setAccessibilityDelegate(v, delegate.getBridge());
408        }
409    }
410
411    static class JBViewCompatImpl extends ICSViewCompatImpl {
412        @Override
413        public boolean hasTransientState(View view) {
414            return ViewCompatJB.hasTransientState(view);
415        }
416        @Override
417        public void setHasTransientState(View view, boolean hasTransientState) {
418            ViewCompatJB.setHasTransientState(view, hasTransientState);
419        }
420        @Override
421        public void postInvalidateOnAnimation(View view) {
422            ViewCompatJB.postInvalidateOnAnimation(view);
423        }
424        @Override
425        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) {
426            ViewCompatJB.postInvalidateOnAnimation(view, left, top, right, bottom);
427        }
428        @Override
429        public void postOnAnimation(View view, Runnable action) {
430            ViewCompatJB.postOnAnimation(view, action);
431        }
432        @Override
433        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
434            ViewCompatJB.postOnAnimationDelayed(view, action, delayMillis);
435        }
436        @Override
437        public int getImportantForAccessibility(View view) {
438            return ViewCompatJB.getImportantForAccessibility(view);
439        }
440        @Override
441        public void setImportantForAccessibility(View view, int mode) {
442            ViewCompatJB.setImportantForAccessibility(view, mode);
443        }
444        @Override
445        public boolean performAccessibilityAction(View view, int action, Bundle arguments) {
446            return ViewCompatJB.performAccessibilityAction(view, action, arguments);
447        }
448        @Override
449        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
450            Object compat = ViewCompatJB.getAccessibilityNodeProvider(view);
451            if (compat != null) {
452                return new AccessibilityNodeProviderCompat(compat);
453            }
454            return null;
455        }
456
457        @Override
458        public ViewParent getParentForAccessibility(View view) {
459            return ViewCompatJB.getParentForAccessibility(view);
460        }
461    }
462
463    static class JbMr1ViewCompatImpl extends JBViewCompatImpl {
464
465        @Override
466        public int getLabelFor(View view) {
467            return ViewCompatJellybeanMr1.getLabelFor(view);
468        }
469
470        @Override
471        public void setLabelFor(View view, int id) {
472            ViewCompatJellybeanMr1.setLabelFor(view, id);
473        }
474
475        @Override
476        public void setLayerPaint(View view, Paint paint) {
477            ViewCompatJellybeanMr1.setLayerPaint(view, paint);
478        }
479
480        @Override
481        public int getLayoutDirection(View view) {
482            return ViewCompatJellybeanMr1.getLayoutDirection(view);
483        }
484
485        @Override
486        public void setLayoutDirection(View view, int layoutDirection) {
487            ViewCompatJellybeanMr1.setLayoutDirection(view, layoutDirection);
488        }
489    }
490
491    static final ViewCompatImpl IMPL;
492    static {
493        final int version = android.os.Build.VERSION.SDK_INT;
494        if (version >= 17) {
495            IMPL = new JbMr1ViewCompatImpl();
496        } else if (version >= 16) {
497            IMPL = new JBViewCompatImpl();
498        } else if (version >= 14) {
499            IMPL = new ICSViewCompatImpl();
500        } else if (version >= 11) {
501            IMPL = new HCViewCompatImpl();
502        } else if (version >= 9) {
503            IMPL = new GBViewCompatImpl();
504        } else {
505            IMPL = new BaseViewCompatImpl();
506        }
507    }
508
509    /**
510     * Check if this view can be scrolled horizontally in a certain direction.
511     *
512     * @param v The View against which to invoke the method.
513     * @param direction Negative to check scrolling left, positive to check scrolling right.
514     * @return true if this view can be scrolled in the specified direction, false otherwise.
515     */
516    public static boolean canScrollHorizontally(View v, int direction) {
517        return IMPL.canScrollHorizontally(v, direction);
518    }
519
520    /**
521     * Check if this view can be scrolled vertically in a certain direction.
522     *
523     * @param v The View against which to invoke the method.
524     * @param direction Negative to check scrolling up, positive to check scrolling down.
525     * @return true if this view can be scrolled in the specified direction, false otherwise.
526     */
527    public static boolean canScrollVertically(View v, int direction) {
528        return IMPL.canScrollVertically(v, direction);
529    }
530
531    /**
532     * Returns the over-scroll mode for this view. The result will be
533     * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
534     * (allow over-scrolling only if the view content is larger than the container),
535     * or {@link #OVER_SCROLL_NEVER}.
536     *
537     * @param v The View against which to invoke the method.
538     * @return This view's over-scroll mode.
539     */
540    public static int getOverScrollMode(View v) {
541        return IMPL.getOverScrollMode(v);
542    }
543
544    /**
545     * Set the over-scroll mode for this view. Valid over-scroll modes are
546     * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
547     * (allow over-scrolling only if the view content is larger than the container),
548     * or {@link #OVER_SCROLL_NEVER}.
549     *
550     * Setting the over-scroll mode of a view will have an effect only if the
551     * view is capable of scrolling.
552     *
553     * @param v The View against which to invoke the method.
554     * @param overScrollMode The new over-scroll mode for this view.
555     */
556    public static void setOverScrollMode(View v, int overScrollMode) {
557        IMPL.setOverScrollMode(v, overScrollMode);
558    }
559
560    /**
561     * Called from {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
562     * giving a chance to this View to populate the accessibility event with its
563     * text content. While this method is free to modify event
564     * attributes other than text content, doing so should normally be performed in
565     * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)}.
566     * <p>
567     * Example: Adding formatted date string to an accessibility event in addition
568     *          to the text added by the super implementation:
569     * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
570     *     super.onPopulateAccessibilityEvent(event);
571     *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
572     *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
573     *         mCurrentDate.getTimeInMillis(), flags);
574     *     event.getText().add(selectedDateUtterance);
575     * }</pre>
576     * <p>
577     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
578     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
579     * {@link android.view.View.AccessibilityDelegate#onPopulateAccessibilityEvent(View,
580     *  AccessibilityEvent)}
581     * is responsible for handling this call.
582     * </p>
583     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
584     * information to the event, in case the default implementation has basic information to add.
585     * </p>
586     *
587     * @param v The View against which to invoke the method.
588     * @param event The accessibility event which to populate.
589     *
590     * @see View#sendAccessibilityEvent(int)
591     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
592     */
593    public static void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
594        IMPL.onPopulateAccessibilityEvent(v, event);
595    }
596
597    /**
598     * Initializes an {@link AccessibilityEvent} with information about
599     * this View which is the event source. In other words, the source of
600     * an accessibility event is the view whose state change triggered firing
601     * the event.
602     * <p>
603     * Example: Setting the password property of an event in addition
604     *          to properties set by the super implementation:
605     * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
606     *     super.onInitializeAccessibilityEvent(event);
607     *     event.setPassword(true);
608     * }</pre>
609     * <p>
610     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
611     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
612     * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityEvent(View,
613     *  AccessibilityEvent)}
614     * is responsible for handling this call.
615     * </p>
616     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
617     * information to the event, in case the default implementation has basic information to add.
618     * </p>
619     *
620     * @param v The View against which to invoke the method.
621     * @param event The event to initialize.
622     *
623     * @see View#sendAccessibilityEvent(int)
624     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
625     */
626    public static void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
627        IMPL.onInitializeAccessibilityEvent(v, event);
628    }
629
630    /**
631     * Initializes an {@link android.view.accessibility.AccessibilityNodeInfo} with information
632     * about this view. The base implementation sets:
633     * <ul>
634     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setParent(View)},</li>
635     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInParent(Rect)},</li>
636     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li>
637     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setPackageName(CharSequence)},</li>
638     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClassName(CharSequence)},</li>
639     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setContentDescription(CharSequence)},</li>
640     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setEnabled(boolean)},</li>
641     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClickable(boolean)},</li>
642     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocusable(boolean)},</li>
643     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocused(boolean)},</li>
644     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setLongClickable(boolean)},</li>
645     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setSelected(boolean)},</li>
646     * </ul>
647     * <p>
648     * Subclasses should override this method, call the super implementation,
649     * and set additional attributes.
650     * </p>
651     * <p>
652     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
653     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
654     * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View,
655     *  android.view.accessibility.AccessibilityNodeInfo)}
656     * is responsible for handling this call.
657     * </p>
658     *
659     * @param v The View against which to invoke the method.
660     * @param info The instance to initialize.
661     */
662    public static void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
663        IMPL.onInitializeAccessibilityNodeInfo(v, info);
664    }
665
666    /**
667     * Sets a delegate for implementing accessibility support via compositon as
668     * opposed to inheritance. The delegate's primary use is for implementing
669     * backwards compatible widgets. For more details see
670     * {@link android.view.View.AccessibilityDelegate}.
671     *
672     * @param v The View against which to invoke the method.
673     * @param delegate The delegate instance.
674     *
675     * @see android.view.View.AccessibilityDelegate
676     */
677    public static void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
678        IMPL.setAccessibilityDelegate(v, delegate);
679    }
680
681    /**
682     * Indicates whether the view is currently tracking transient state that the
683     * app should not need to concern itself with saving and restoring, but that
684     * the framework should take special note to preserve when possible.
685     *
686     * @param view View to check for transient state
687     * @return true if the view has transient state
688     */
689    public static boolean hasTransientState(View view) {
690        return IMPL.hasTransientState(view);
691    }
692
693    /**
694     * Set whether this view is currently tracking transient state that the
695     * framework should attempt to preserve when possible.
696     *
697     * @param view View tracking transient state
698     * @param hasTransientState true if this view has transient state
699     */
700    public static void setHasTransientState(View view, boolean hasTransientState) {
701        IMPL.setHasTransientState(view, hasTransientState);
702    }
703
704    /**
705     * <p>Cause an invalidate to happen on the next animation time step, typically the
706     * next display frame.</p>
707     *
708     * <p>This method can be invoked from outside of the UI thread
709     * only when this View is attached to a window.</p>
710     *
711     * @param view View to invalidate
712     */
713    public static void postInvalidateOnAnimation(View view) {
714        IMPL.postInvalidateOnAnimation(view);
715    }
716
717    /**
718     * <p>Cause an invalidate of the specified area to happen on the next animation
719     * time step, typically the next display frame.</p>
720     *
721     * <p>This method can be invoked from outside of the UI thread
722     * only when this View is attached to a window.</p>
723     *
724     * @param view View to invalidate
725     * @param left The left coordinate of the rectangle to invalidate.
726     * @param top The top coordinate of the rectangle to invalidate.
727     * @param right The right coordinate of the rectangle to invalidate.
728     * @param bottom The bottom coordinate of the rectangle to invalidate.
729     */
730    public static void postInvalidateOnAnimation(View view, int left, int top,
731            int right, int bottom) {
732        IMPL.postInvalidateOnAnimation(view, left, top, right, bottom);
733    }
734
735    /**
736     * <p>Causes the Runnable to execute on the next animation time step.
737     * The runnable will be run on the user interface thread.</p>
738     *
739     * <p>This method can be invoked from outside of the UI thread
740     * only when this View is attached to a window.</p>
741     *
742     * @param view View to post this Runnable to
743     * @param action The Runnable that will be executed.
744     */
745    public static void postOnAnimation(View view, Runnable action) {
746        IMPL.postOnAnimation(view, action);
747    }
748
749    /**
750     * <p>Causes the Runnable to execute on the next animation time step,
751     * after the specified amount of time elapses.
752     * The runnable will be run on the user interface thread.</p>
753     *
754     * <p>This method can be invoked from outside of the UI thread
755     * only when this View is attached to a window.</p>
756     *
757     * @param view The view to post this Runnable to
758     * @param action The Runnable that will be executed.
759     * @param delayMillis The delay (in milliseconds) until the Runnable
760     *        will be executed.
761     */
762    public static void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
763        IMPL.postOnAnimationDelayed(view, action, delayMillis);
764    }
765
766    /**
767     * Gets the mode for determining whether this View is important for accessibility
768     * which is if it fires accessibility events and if it is reported to
769     * accessibility services that query the screen.
770     *
771     * @param view The view whose property to get.
772     * @return The mode for determining whether a View is important for accessibility.
773     *
774     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
775     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
776     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
777     */
778    public static int getImportantForAccessibility(View view) {
779        return IMPL.getImportantForAccessibility(view);
780    }
781
782    /**
783     * Sets how to determine whether this view is important for accessibility
784     * which is if it fires accessibility events and if it is reported to
785     * accessibility services that query the screen.
786     *
787     * @param view The view whose property to set.
788     * @param mode How to determine whether this view is important for accessibility.
789     *
790     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
791     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
792     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
793     */
794    public static void setImportantForAccessibility(View view, int mode) {
795        IMPL.setImportantForAccessibility(view, mode);
796    }
797
798    /**
799     * Performs the specified accessibility action on the view. For
800     * possible accessibility actions look at {@link AccessibilityNodeInfoCompat}.
801     * <p>
802     * If an {@link AccessibilityDelegateCompat} has been specified via calling
803     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
804     * {@link AccessibilityDelegateCompat#performAccessibilityAction(View, int, Bundle)}
805     * is responsible for handling this call.
806     * </p>
807     *
808     * @param action The action to perform.
809     * @param arguments Optional action arguments.
810     * @return Whether the action was performed.
811     */
812    public static boolean performAccessibilityAction(View view, int action, Bundle arguments) {
813        return IMPL.performAccessibilityAction(view, action, arguments);
814    }
815
816    /**
817     * Gets the provider for managing a virtual view hierarchy rooted at this View
818     * and reported to {@link android.accessibilityservice.AccessibilityService}s
819     * that explore the window content.
820     * <p>
821     * If this method returns an instance, this instance is responsible for managing
822     * {@link AccessibilityNodeInfoCompat}s describing the virtual sub-tree rooted at
823     * this View including the one representing the View itself. Similarly the returned
824     * instance is responsible for performing accessibility actions on any virtual
825     * view or the root view itself.
826     * </p>
827     * <p>
828     * If an {@link AccessibilityDelegateCompat} has been specified via calling
829     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
830     * {@link AccessibilityDelegateCompat#getAccessibilityNodeProvider(View)}
831     * is responsible for handling this call.
832     * </p>
833     *
834     * @param view The view whose property to get.
835     * @return The provider.
836     *
837     * @see AccessibilityNodeProviderCompat
838     */
839    public static AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
840        return IMPL.getAccessibilityNodeProvider(view);
841    }
842
843    /**
844     * The opacity of the view. This is a value from 0 to 1, where 0 means the view is
845     * completely transparent and 1 means the view is completely opaque.
846     *
847     * <p>By default this is 1.0f. Prior to API 11, the returned value is always 1.0f.
848     * @return The opacity of the view.
849     */
850    public static float getAlpha(View view) {
851        return IMPL.getAlpha(view);
852    }
853
854    /**
855     * <p>Specifies the type of layer backing this view. The layer can be
856     * {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or
857     * {@link #LAYER_TYPE_HARDWARE hardware}.</p>
858     *
859     * <p>A layer is associated with an optional {@link android.graphics.Paint}
860     * instance that controls how the layer is composed on screen. The following
861     * properties of the paint are taken into account when composing the layer:</p>
862     * <ul>
863     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
864     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
865     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
866     * </ul>
867     *
868     * <p>If this view has an alpha value set to < 1.0 by calling
869     * setAlpha(float), the alpha value of the layer's paint is replaced by
870     * this view's alpha value. Calling setAlpha(float) is therefore
871     * equivalent to setting a hardware layer on this view and providing a paint with
872     * the desired alpha value.<p>
873     *
874     * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled},
875     * {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware}
876     * for more information on when and how to use layers.</p>
877     *
878     * @param layerType The ype of layer to use with this view, must be one of
879     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
880     *        {@link #LAYER_TYPE_HARDWARE}
881     * @param paint The paint used to compose the layer. This argument is optional
882     *        and can be null. It is ignored when the layer type is
883     *        {@link #LAYER_TYPE_NONE}
884     *
885     * @param view View to set the layer type for
886     * @param layerType The type of layer to use with this view, must be one of
887     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
888     *        {@link #LAYER_TYPE_HARDWARE}
889     * @param paint The paint used to compose the layer. This argument is optional
890     *        and can be null. It is ignored when the layer type is
891     *        {@link #LAYER_TYPE_NONE}
892     */
893    public static void setLayerType(View view, int layerType, Paint paint) {
894        IMPL.setLayerType(view, layerType, paint);
895    }
896
897    /**
898     * Indicates what type of layer is currently associated with this view. By default
899     * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
900     * Refer to the documentation of
901     * {@link #setLayerType(android.view.View, int, android.graphics.Paint)}
902     * for more information on the different types of layers.
903     *
904     * @param view The view to fetch the layer type from
905     * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
906     *         {@link #LAYER_TYPE_HARDWARE}
907     *
908     * @see #setLayerType(android.view.View, int, android.graphics.Paint)
909     * @see #LAYER_TYPE_NONE
910     * @see #LAYER_TYPE_SOFTWARE
911     * @see #LAYER_TYPE_HARDWARE
912     */
913    public static int getLayerType(View view) {
914        return IMPL.getLayerType(view);
915    }
916
917    /**
918     * Gets the id of a view for which a given view serves as a label for
919     * accessibility purposes.
920     *
921     * @param view The view on which to invoke the corresponding method.
922     * @return The labeled view id.
923     */
924    public static int getLabelFor(View view) {
925        return IMPL.getLabelFor(view);
926    }
927
928    /**
929     * Sets the id of a view for which a given view serves as a label for
930     * accessibility purposes.
931     *
932     * @param view The view on which to invoke the corresponding method.
933     * @param labeledId The labeled view id.
934     */
935    public static void setLabelFor(View view, int labeledId) {
936        IMPL.setLabelFor(view, labeledId);
937    }
938
939    /**
940     * Updates the {@link Paint} object used with the current layer (used only if the current
941     * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
942     * provided to {@link #setLayerType(android.view.View, int, android.graphics.Paint)}
943     * will be used the next time the View is redrawn, but
944     * {@link #setLayerPaint(android.view.View, android.graphics.Paint)}
945     * must be called to ensure that the view gets redrawn immediately.
946     *
947     * <p>A layer is associated with an optional {@link android.graphics.Paint}
948     * instance that controls how the layer is composed on screen. The following
949     * properties of the paint are taken into account when composing the layer:</p>
950     * <ul>
951     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
952     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
953     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
954     * </ul>
955     *
956     * <p>If this view has an alpha value set to < 1.0 by calling
957     * View#setAlpha(float), the alpha value of the layer's paint is replaced by
958     * this view's alpha value. Calling View#setAlpha(float) is therefore
959     * equivalent to setting a hardware layer on this view and providing a paint with
960     * the desired alpha value.</p>
961     *
962     * @param view View to set a layer paint for
963     * @param paint The paint used to compose the layer. This argument is optional
964     *        and can be null. It is ignored when the layer type is
965     *        {@link #LAYER_TYPE_NONE}
966     *
967     * @see #setLayerType(View, int, android.graphics.Paint)
968     */
969    public static void setLayerPaint(View view, Paint paint) {
970        IMPL.setLayerPaint(view, paint);
971    }
972
973    /**
974     * Returns the resolved layout direction for this view.
975     *
976     * @param view View to get layout direction for
977     * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
978     * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
979     *
980     * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version
981     * is lower than Jellybean MR1 (API 17)
982     */
983    public static int getLayoutDirection(View view) {
984        return IMPL.getLayoutDirection(view);
985    }
986
987    /**
988     * Set the layout direction for this view. This will propagate a reset of layout direction
989     * resolution to the view's children and resolve layout direction for this view.
990     *
991     * @param view View to set layout direction for
992     * @param layoutDirection the layout direction to set. Should be one of:
993     *
994     * {@link #LAYOUT_DIRECTION_LTR},
995     * {@link #LAYOUT_DIRECTION_RTL},
996     * {@link #LAYOUT_DIRECTION_INHERIT},
997     * {@link #LAYOUT_DIRECTION_LOCALE}.
998     *
999     * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution
1000     * proceeds up the parent chain of the view to get the value. If there is no parent, then it
1001     * will return the default {@link #LAYOUT_DIRECTION_LTR}.
1002     */
1003    public static void setLayoutDirection(View view, int layoutDirection) {
1004        IMPL.setLayoutDirection(view, layoutDirection);
1005    }
1006
1007    /**
1008     * Gets the parent for accessibility purposes. Note that the parent for
1009     * accessibility is not necessary the immediate parent. It is the first
1010     * predecessor that is important for accessibility.
1011     *
1012     * @param view View to retrieve parent for
1013     * @return The parent for use in accessibility inspection
1014     */
1015    public static ViewParent getParentForAccessibility(View view) {
1016        return IMPL.getParentForAccessibility(view);
1017    }
1018
1019    /**
1020     * Indicates whether this View is opaque. An opaque View guarantees that it will
1021     * draw all the pixels overlapping its bounds using a fully opaque color.
1022     *
1023     * On API 7 and above this will call View's true isOpaque method. On previous platform
1024     * versions it will check the opacity of the view's background drawable if present.
1025     *
1026     * @return True if this View is guaranteed to be fully opaque, false otherwise.
1027     */
1028    public static boolean isOpaque(View view) {
1029        return IMPL.isOpaque(view);
1030    }
1031
1032    /**
1033     * Utility to reconcile a desired size and state, with constraints imposed
1034     * by a MeasureSpec.  Will take the desired size, unless a different size
1035     * is imposed by the constraints.  The returned value is a compound integer,
1036     * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
1037     * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting
1038     * size is smaller than the size the view wants to be.
1039     *
1040     * @param size How big the view wants to be
1041     * @param measureSpec Constraints imposed by the parent
1042     * @return Size information bit mask as defined by
1043     * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
1044     */
1045    public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
1046        return IMPL.resolveSizeAndState(size, measureSpec, childMeasuredState);
1047    }
1048
1049    /**
1050     * Return the full width measurement information for this view as computed
1051     * by the most recent call to {@link android.view.View#measure(int, int)}.
1052     * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and
1053     * {@link #MEASURED_STATE_TOO_SMALL}.
1054     * This should be used during measurement and layout calculations only. Use
1055     * {@link android.view.View#getWidth()} to see how wide a view is after layout.
1056     *
1057     * @return The measured width of this view as a bit mask.
1058     */
1059    public static int getMeasuredWidthAndState(View view) {
1060        return IMPL.getMeasuredWidthAndState(view);
1061    }
1062
1063    /**
1064     * Return the full height measurement information for this view as computed
1065     * by the most recent call to {@link android.view.View#measure(int, int)}.
1066     * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and
1067     * {@link #MEASURED_STATE_TOO_SMALL}.
1068     * This should be used during measurement and layout calculations only. Use
1069     * {@link android.view.View#getHeight()} to see how wide a view is after layout.
1070     *
1071     * @return The measured width of this view as a bit mask.
1072     */
1073    public static int getMeasuredHeightAndState(View view) {
1074        return IMPL.getMeasuredHeightAndState(view);
1075    }
1076
1077    /**
1078     * Return only the state bits of {@link #getMeasuredWidthAndState}
1079     * and {@link #getMeasuredHeightAndState}, combined into one integer.
1080     * The width component is in the regular bits {@link #MEASURED_STATE_MASK}
1081     * and the height component is at the shifted bits
1082     * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}.
1083     */
1084    public static int getMeasuredState(View view) {
1085        return IMPL.getMeasuredState(view);
1086    }
1087}
1088