ViewCompat.java revision b1bfdf4c03d1b25959c5818805b997020f7ed085
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.ViewParent; 31import android.view.accessibility.AccessibilityEvent; 32 33import java.lang.annotation.Retention; 34import java.lang.annotation.RetentionPolicy; 35import java.lang.reflect.InvocationTargetException; 36import java.lang.reflect.Method; 37 38/** 39 * Helper for accessing features in {@link View} introduced after API 40 * level 4 in a backwards compatible fashion. 41 */ 42public class ViewCompat { 43 private static final String TAG = "ViewCompat"; 44 45 /** @hide */ 46 @IntDef({OVER_SCROLL_ALWAYS, OVER_SCROLL_IF_CONTENT_SCROLLS, OVER_SCROLL_IF_CONTENT_SCROLLS}) 47 @Retention(RetentionPolicy.SOURCE) 48 private @interface OverScroll {} 49 50 /** 51 * Always allow a user to over-scroll this view, provided it is a 52 * view that can scroll. 53 */ 54 public static final int OVER_SCROLL_ALWAYS = 0; 55 56 /** 57 * Allow a user to over-scroll this view only if the content is large 58 * enough to meaningfully scroll, provided it is a view that can scroll. 59 */ 60 public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; 61 62 /** 63 * Never allow a user to over-scroll this view. 64 */ 65 public static final int OVER_SCROLL_NEVER = 2; 66 67 private static final long FAKE_FRAME_TIME = 10; 68 69 /** @hide */ 70 @IntDef({ 71 IMPORTANT_FOR_ACCESSIBILITY_AUTO, 72 IMPORTANT_FOR_ACCESSIBILITY_YES, 73 IMPORTANT_FOR_ACCESSIBILITY_NO, 74 IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS 75 }) 76 @Retention(RetentionPolicy.SOURCE) 77 private @interface ImportantForAccessibility {} 78 79 /** 80 * Automatically determine whether a view is important for accessibility. 81 */ 82 public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000; 83 84 /** 85 * The view is important for accessibility. 86 */ 87 public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001; 88 89 /** 90 * The view is not important for accessibility. 91 */ 92 public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002; 93 94 /** 95 * The view is not important for accessibility, nor are any of its 96 * descendant views. 97 */ 98 public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004; 99 100 /** @hide */ 101 @IntDef({ 102 ACCESSIBILITY_LIVE_REGION_NONE, 103 ACCESSIBILITY_LIVE_REGION_POLITE, 104 ACCESSIBILITY_LIVE_REGION_ASSERTIVE 105 }) 106 @Retention(RetentionPolicy.SOURCE) 107 private @interface AccessibilityLiveRegion {} 108 109 /** 110 * Live region mode specifying that accessibility services should not 111 * automatically announce changes to this view. This is the default live 112 * region mode for most views. 113 * <p> 114 * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}. 115 */ 116 public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000; 117 118 /** 119 * Live region mode specifying that accessibility services should announce 120 * changes to this view. 121 * <p> 122 * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}. 123 */ 124 public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001; 125 126 /** 127 * Live region mode specifying that accessibility services should interrupt 128 * ongoing speech to immediately announce changes to this view. 129 * <p> 130 * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}. 131 */ 132 public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002; 133 134 /** @hide */ 135 @IntDef({LAYER_TYPE_NONE, LAYER_TYPE_SOFTWARE, LAYER_TYPE_HARDWARE}) 136 @Retention(RetentionPolicy.SOURCE) 137 private @interface LayerType {} 138 139 /** 140 * Indicates that the view does not have a layer. 141 */ 142 public static final int LAYER_TYPE_NONE = 0; 143 144 /** 145 * <p>Indicates that the view has a software layer. A software layer is backed 146 * by a bitmap and causes the view to be rendered using Android's software 147 * rendering pipeline, even if hardware acceleration is enabled.</p> 148 * 149 * <p>Software layers have various usages:</p> 150 * <p>When the application is not using hardware acceleration, a software layer 151 * is useful to apply a specific color filter and/or blending mode and/or 152 * translucency to a view and all its children.</p> 153 * <p>When the application is using hardware acceleration, a software layer 154 * is useful to render drawing primitives not supported by the hardware 155 * accelerated pipeline. It can also be used to cache a complex view tree 156 * into a texture and reduce the complexity of drawing operations. For instance, 157 * when animating a complex view tree with a translation, a software layer can 158 * be used to render the view tree only once.</p> 159 * <p>Software layers should be avoided when the affected view tree updates 160 * often. Every update will require to re-render the software layer, which can 161 * potentially be slow (particularly when hardware acceleration is turned on 162 * since the layer will have to be uploaded into a hardware texture after every 163 * update.)</p> 164 */ 165 public static final int LAYER_TYPE_SOFTWARE = 1; 166 167 /** 168 * <p>Indicates that the view has a hardware layer. A hardware layer is backed 169 * by a hardware specific texture (generally Frame Buffer Objects or FBO on 170 * OpenGL hardware) and causes the view to be rendered using Android's hardware 171 * rendering pipeline, but only if hardware acceleration is turned on for the 172 * view hierarchy. When hardware acceleration is turned off, hardware layers 173 * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p> 174 * 175 * <p>A hardware layer is useful to apply a specific color filter and/or 176 * blending mode and/or translucency to a view and all its children.</p> 177 * <p>A hardware layer can be used to cache a complex view tree into a 178 * texture and reduce the complexity of drawing operations. For instance, 179 * when animating a complex view tree with a translation, a hardware layer can 180 * be used to render the view tree only once.</p> 181 * <p>A hardware layer can also be used to increase the rendering quality when 182 * rotation transformations are applied on a view. It can also be used to 183 * prevent potential clipping issues when applying 3D transforms on a view.</p> 184 */ 185 public static final int LAYER_TYPE_HARDWARE = 2; 186 187 /** @hide */ 188 @IntDef({ 189 LAYOUT_DIRECTION_LTR, 190 LAYOUT_DIRECTION_RTL, 191 LAYOUT_DIRECTION_INHERIT, 192 LAYOUT_DIRECTION_LOCALE}) 193 @Retention(RetentionPolicy.SOURCE) 194 private @interface LayoutDirectionMode {} 195 196 /** @hide */ 197 @IntDef({ 198 LAYOUT_DIRECTION_LTR, 199 LAYOUT_DIRECTION_RTL 200 }) 201 @Retention(RetentionPolicy.SOURCE) 202 private @interface ResolvedLayoutDirectionMode {} 203 204 /** 205 * Horizontal layout direction of this view is from Left to Right. 206 */ 207 public static final int LAYOUT_DIRECTION_LTR = 0; 208 209 /** 210 * Horizontal layout direction of this view is from Right to Left. 211 */ 212 public static final int LAYOUT_DIRECTION_RTL = 1; 213 214 /** 215 * Horizontal layout direction of this view is inherited from its parent. 216 * Use with {@link #setLayoutDirection}. 217 */ 218 public static final int LAYOUT_DIRECTION_INHERIT = 2; 219 220 /** 221 * Horizontal layout direction of this view is from deduced from the default language 222 * script for the locale. Use with {@link #setLayoutDirection}. 223 */ 224 public static final int LAYOUT_DIRECTION_LOCALE = 3; 225 226 /** 227 * Bits of {@link #getMeasuredWidthAndState} and 228 * {@link #getMeasuredWidthAndState} that provide the actual measured size. 229 */ 230 public static final int MEASURED_SIZE_MASK = 0x00ffffff; 231 232 /** 233 * Bits of {@link #getMeasuredWidthAndState} and 234 * {@link #getMeasuredWidthAndState} that provide the additional state bits. 235 */ 236 public static final int MEASURED_STATE_MASK = 0xff000000; 237 238 /** 239 * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits 240 * for functions that combine both width and height into a single int, 241 * such as {@link #getMeasuredState} and the childState argument of 242 * {@link #resolveSizeAndState(int, int, int)}. 243 */ 244 public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; 245 246 /** 247 * Bit of {@link #getMeasuredWidthAndState} and 248 * {@link #getMeasuredWidthAndState} that indicates the measured size 249 * is smaller that the space the view would like to have. 250 */ 251 public static final int MEASURED_STATE_TOO_SMALL = 0x01000000; 252 253 interface ViewCompatImpl { 254 public boolean canScrollHorizontally(View v, int direction); 255 public boolean canScrollVertically(View v, int direction); 256 public int getOverScrollMode(View v); 257 public void setOverScrollMode(View v, int mode); 258 public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event); 259 public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event); 260 public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info); 261 public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate); 262 public boolean hasTransientState(View view); 263 public void setHasTransientState(View view, boolean hasTransientState); 264 public void postInvalidateOnAnimation(View view); 265 public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom); 266 public void postOnAnimation(View view, Runnable action); 267 public void postOnAnimationDelayed(View view, Runnable action, long delayMillis); 268 public int getImportantForAccessibility(View view); 269 public void setImportantForAccessibility(View view, int mode); 270 public boolean performAccessibilityAction(View view, int action, Bundle arguments); 271 public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view); 272 public float getAlpha(View view); 273 public void setLayerType(View view, int layerType, Paint paint); 274 public int getLayerType(View view); 275 public int getLabelFor(View view); 276 public void setLabelFor(View view, int id); 277 public void setLayerPaint(View view, Paint paint); 278 public int getLayoutDirection(View view); 279 public void setLayoutDirection(View view, int layoutDirection); 280 public ViewParent getParentForAccessibility(View view); 281 public boolean isOpaque(View view); 282 public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState); 283 public int getMeasuredWidthAndState(View view); 284 public int getMeasuredHeightAndState(View view); 285 public int getMeasuredState(View view); 286 public int getAccessibilityLiveRegion(View view); 287 public void setAccessibilityLiveRegion(View view, int mode); 288 public int getPaddingStart(View view); 289 public int getPaddingEnd(View view); 290 public void setPaddingRelative(View view, int start, int top, int end, int bottom); 291 public void dispatchStartTemporaryDetach(View view); 292 public void dispatchFinishTemporaryDetach(View view); 293 public float getTranslationX(View view); 294 public float getTranslationY(View view); 295 public int getMinimumWidth(View view); 296 public int getMinimumHeight(View view); 297 } 298 299 static class BaseViewCompatImpl implements ViewCompatImpl { 300 private Method mDispatchStartTemporaryDetach; 301 private Method mDispatchFinishTemporaryDetach; 302 private boolean mTempDetachBound; 303 304 public boolean canScrollHorizontally(View v, int direction) { 305 return false; 306 } 307 public boolean canScrollVertically(View v, int direction) { 308 return false; 309 } 310 public int getOverScrollMode(View v) { 311 return OVER_SCROLL_NEVER; 312 } 313 public void setOverScrollMode(View v, int mode) { 314 // Do nothing; API doesn't exist 315 } 316 public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) { 317 // Do nothing; API doesn't exist 318 } 319 public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) { 320 // Do nothing; API doesn't exist 321 } 322 public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) { 323 // Do nothing; API doesn't exist 324 } 325 public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) { 326 // Do nothing; API doesn't exist 327 } 328 public boolean hasTransientState(View view) { 329 // A view can't have transient state if transient state wasn't supported. 330 return false; 331 } 332 public void setHasTransientState(View view, boolean hasTransientState) { 333 // Do nothing; API doesn't exist 334 } 335 public void postInvalidateOnAnimation(View view) { 336 view.invalidate(); 337 } 338 public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) { 339 view.invalidate(left, top, right, bottom); 340 } 341 public void postOnAnimation(View view, Runnable action) { 342 view.postDelayed(action, getFrameTime()); 343 } 344 public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) { 345 view.postDelayed(action, getFrameTime() + delayMillis); 346 } 347 long getFrameTime() { 348 return FAKE_FRAME_TIME; 349 } 350 public int getImportantForAccessibility(View view) { 351 return 0; 352 } 353 public void setImportantForAccessibility(View view, int mode) { 354 355 } 356 public boolean performAccessibilityAction(View view, int action, Bundle arguments) { 357 return false; 358 } 359 public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) { 360 return null; 361 } 362 public float getAlpha(View view) { 363 return 1.0f; 364 } 365 public void setLayerType(View view, int layerType, Paint paint) { 366 // No-op until layers became available (HC) 367 } 368 public int getLayerType(View view) { 369 return LAYER_TYPE_NONE; 370 } 371 public int getLabelFor(View view) { 372 return 0; 373 } 374 public void setLabelFor(View view, int id) { 375 376 } 377 public void setLayerPaint(View view, Paint p) { 378 // No-op until layers became available (HC) 379 } 380 381 @Override 382 public int getLayoutDirection(View view) { 383 return LAYOUT_DIRECTION_LTR; 384 } 385 386 @Override 387 public void setLayoutDirection(View view, int layoutDirection) { 388 // No-op 389 } 390 391 @Override 392 public ViewParent getParentForAccessibility(View view) { 393 return view.getParent(); 394 } 395 396 @Override 397 public boolean isOpaque(View view) { 398 final Drawable bg = view.getBackground(); 399 if (bg != null) { 400 return bg.getOpacity() == PixelFormat.OPAQUE; 401 } 402 return false; 403 } 404 405 public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) { 406 return View.resolveSize(size, measureSpec); 407 } 408 409 @Override 410 public int getMeasuredWidthAndState(View view) { 411 return view.getMeasuredWidth(); 412 } 413 414 @Override 415 public int getMeasuredHeightAndState(View view) { 416 return view.getMeasuredHeight(); 417 } 418 419 @Override 420 public int getMeasuredState(View view) { 421 return 0; 422 } 423 424 @Override 425 public int getAccessibilityLiveRegion(View view) { 426 return ACCESSIBILITY_LIVE_REGION_NONE; 427 } 428 429 @Override 430 public void setAccessibilityLiveRegion(View view, int mode) { 431 // No-op 432 } 433 434 @Override 435 public int getPaddingStart(View view) { 436 return view.getPaddingLeft(); 437 } 438 439 @Override 440 public int getPaddingEnd(View view) { 441 return view.getPaddingRight(); 442 } 443 444 @Override 445 public void setPaddingRelative(View view, int start, int top, int end, int bottom) { 446 view.setPadding(start, top, end, bottom); 447 } 448 449 @Override 450 public void dispatchStartTemporaryDetach(View view) { 451 if (!mTempDetachBound) { 452 bindTempDetach(); 453 } 454 if (mDispatchStartTemporaryDetach != null) { 455 try { 456 mDispatchStartTemporaryDetach.invoke(view); 457 } catch (Exception e) { 458 Log.d(TAG, "Error calling dispatchStartTemporaryDetach", e); 459 } 460 } else { 461 // Try this instead 462 view.onStartTemporaryDetach(); 463 } 464 } 465 466 @Override 467 public void dispatchFinishTemporaryDetach(View view) { 468 if (!mTempDetachBound) { 469 bindTempDetach(); 470 } 471 if (mDispatchFinishTemporaryDetach != null) { 472 try { 473 mDispatchFinishTemporaryDetach.invoke(view); 474 } catch (Exception e) { 475 Log.d(TAG, "Error calling dispatchFinishTemporaryDetach", e); 476 } 477 } else { 478 // Try this instead 479 view.onFinishTemporaryDetach(); 480 } 481 } 482 483 private void bindTempDetach() { 484 try { 485 mDispatchStartTemporaryDetach = View.class.getDeclaredMethod( 486 "dispatchStartTemporaryDetach"); 487 mDispatchFinishTemporaryDetach = View.class.getDeclaredMethod( 488 "dispatchFinishTemporaryDetach"); 489 } catch (NoSuchMethodException e) { 490 Log.e(TAG, "Couldn't find method", e); 491 } 492 mTempDetachBound = true; 493 } 494 495 @Override 496 public float getTranslationX(View view) { 497 return 0; 498 } 499 500 @Override 501 public float getTranslationY(View view) { 502 return 0; 503 } 504 505 @Override 506 public int getMinimumWidth(View view) { 507 return 0; 508 } 509 510 @Override 511 public int getMinimumHeight(View view) { 512 return 0; 513 } 514 } 515 516 static class EclairMr1ViewCompatImpl extends BaseViewCompatImpl { 517 @Override 518 public boolean isOpaque(View view) { 519 return ViewCompatEclairMr1.isOpaque(view); 520 } 521 } 522 523 static class GBViewCompatImpl extends EclairMr1ViewCompatImpl { 524 @Override 525 public int getOverScrollMode(View v) { 526 return ViewCompatGingerbread.getOverScrollMode(v); 527 } 528 @Override 529 public void setOverScrollMode(View v, int mode) { 530 ViewCompatGingerbread.setOverScrollMode(v, mode); 531 } 532 } 533 534 static class HCViewCompatImpl extends GBViewCompatImpl { 535 @Override 536 long getFrameTime() { 537 return ViewCompatHC.getFrameTime(); 538 } 539 @Override 540 public float getAlpha(View view) { 541 return ViewCompatHC.getAlpha(view); 542 } 543 @Override 544 public void setLayerType(View view, int layerType, Paint paint) { 545 ViewCompatHC.setLayerType(view, layerType, paint); 546 } 547 @Override 548 public int getLayerType(View view) { 549 return ViewCompatHC.getLayerType(view); 550 } 551 @Override 552 public void setLayerPaint(View view, Paint paint) { 553 // Make sure the paint is correct; this will be cheap if it's the same 554 // instance as was used to call setLayerType earlier. 555 setLayerType(view, getLayerType(view), paint); 556 // This is expensive, but the only way to accomplish this before JB-MR1. 557 view.invalidate(); 558 } 559 @Override 560 public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) { 561 return ViewCompatHC.resolveSizeAndState(size, measureSpec, childMeasuredState); 562 } 563 @Override 564 public int getMeasuredWidthAndState(View view) { 565 return ViewCompatHC.getMeasuredWidthAndState(view); 566 } 567 @Override 568 public int getMeasuredHeightAndState(View view) { 569 return ViewCompatHC.getMeasuredHeightAndState(view); 570 } 571 @Override 572 public int getMeasuredState(View view) { 573 return ViewCompatHC.getMeasuredState(view); 574 } 575 @Override 576 public float getTranslationX(View view) { 577 return ViewCompatHC.getTranslationX(view); 578 } 579 @Override 580 public float getTranslationY(View view) { 581 return ViewCompatHC.getTranslationY(view); 582 } 583 } 584 585 static class ICSViewCompatImpl extends HCViewCompatImpl { 586 @Override 587 public boolean canScrollHorizontally(View v, int direction) { 588 return ViewCompatICS.canScrollHorizontally(v, direction); 589 } 590 @Override 591 public boolean canScrollVertically(View v, int direction) { 592 return ViewCompatICS.canScrollVertically(v, direction); 593 } 594 @Override 595 public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) { 596 ViewCompatICS.onPopulateAccessibilityEvent(v, event); 597 } 598 @Override 599 public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) { 600 ViewCompatICS.onInitializeAccessibilityEvent(v, event); 601 } 602 @Override 603 public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) { 604 ViewCompatICS.onInitializeAccessibilityNodeInfo(v, info.getInfo()); 605 } 606 @Override 607 public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) { 608 ViewCompatICS.setAccessibilityDelegate(v, delegate.getBridge()); 609 } 610 } 611 612 static class JBViewCompatImpl extends ICSViewCompatImpl { 613 @Override 614 public boolean hasTransientState(View view) { 615 return ViewCompatJB.hasTransientState(view); 616 } 617 @Override 618 public void setHasTransientState(View view, boolean hasTransientState) { 619 ViewCompatJB.setHasTransientState(view, hasTransientState); 620 } 621 @Override 622 public void postInvalidateOnAnimation(View view) { 623 ViewCompatJB.postInvalidateOnAnimation(view); 624 } 625 @Override 626 public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) { 627 ViewCompatJB.postInvalidateOnAnimation(view, left, top, right, bottom); 628 } 629 @Override 630 public void postOnAnimation(View view, Runnable action) { 631 ViewCompatJB.postOnAnimation(view, action); 632 } 633 @Override 634 public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) { 635 ViewCompatJB.postOnAnimationDelayed(view, action, delayMillis); 636 } 637 @Override 638 public int getImportantForAccessibility(View view) { 639 return ViewCompatJB.getImportantForAccessibility(view); 640 } 641 @Override 642 public void setImportantForAccessibility(View view, int mode) { 643 // IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS is not available 644 // on this platform so replace with IMPORTANT_FOR_ACCESSIBILITY_NO 645 // which is closer semantically. 646 if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) { 647 mode = IMPORTANT_FOR_ACCESSIBILITY_NO; 648 } 649 ViewCompatJB.setImportantForAccessibility(view, mode); 650 } 651 @Override 652 public boolean performAccessibilityAction(View view, int action, Bundle arguments) { 653 return ViewCompatJB.performAccessibilityAction(view, action, arguments); 654 } 655 @Override 656 public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) { 657 Object compat = ViewCompatJB.getAccessibilityNodeProvider(view); 658 if (compat != null) { 659 return new AccessibilityNodeProviderCompat(compat); 660 } 661 return null; 662 } 663 664 @Override 665 public ViewParent getParentForAccessibility(View view) { 666 return ViewCompatJB.getParentForAccessibility(view); 667 } 668 669 @Override 670 public int getMinimumWidth(View view) { 671 return ViewCompatJB.getMinimumWidth(view); 672 } 673 674 @Override 675 public int getMinimumHeight(View view) { 676 return ViewCompatJB.getMinimumHeight(view); 677 } 678 } 679 680 static class JbMr1ViewCompatImpl extends JBViewCompatImpl { 681 682 @Override 683 public int getLabelFor(View view) { 684 return ViewCompatJellybeanMr1.getLabelFor(view); 685 } 686 687 @Override 688 public void setLabelFor(View view, int id) { 689 ViewCompatJellybeanMr1.setLabelFor(view, id); 690 } 691 692 @Override 693 public void setLayerPaint(View view, Paint paint) { 694 ViewCompatJellybeanMr1.setLayerPaint(view, paint); 695 } 696 697 @Override 698 public int getLayoutDirection(View view) { 699 return ViewCompatJellybeanMr1.getLayoutDirection(view); 700 } 701 702 @Override 703 public void setLayoutDirection(View view, int layoutDirection) { 704 ViewCompatJellybeanMr1.setLayoutDirection(view, layoutDirection); 705 } 706 707 @Override 708 public int getPaddingStart(View view) { 709 return ViewCompatJellybeanMr1.getPaddingStart(view); 710 } 711 712 @Override 713 public int getPaddingEnd(View view) { 714 return ViewCompatJellybeanMr1.getPaddingEnd(view); 715 } 716 717 @Override 718 public void setPaddingRelative(View view, int start, int top, int end, int bottom) { 719 ViewCompatJellybeanMr1.setPaddingRelative(view, start, top, end, bottom); 720 } 721 } 722 723 static class KitKatViewCompatImpl extends JbMr1ViewCompatImpl { 724 @Override 725 public int getAccessibilityLiveRegion(View view) { 726 return ViewCompatKitKat.getAccessibilityLiveRegion(view); 727 } 728 729 @Override 730 public void setAccessibilityLiveRegion(View view, int mode) { 731 ViewCompatKitKat.setAccessibilityLiveRegion(view, mode); 732 } 733 734 @Override 735 public void setImportantForAccessibility(View view, int mode) { 736 ViewCompatJB.setImportantForAccessibility(view, mode); 737 } 738 } 739 740 static final ViewCompatImpl IMPL; 741 static { 742 final int version = android.os.Build.VERSION.SDK_INT; 743 if (version >= 19) { 744 IMPL = new KitKatViewCompatImpl(); 745 } else if (version >= 17) { 746 IMPL = new JbMr1ViewCompatImpl(); 747 } else if (version >= 16) { 748 IMPL = new JBViewCompatImpl(); 749 } else if (version >= 14) { 750 IMPL = new ICSViewCompatImpl(); 751 } else if (version >= 11) { 752 IMPL = new HCViewCompatImpl(); 753 } else if (version >= 9) { 754 IMPL = new GBViewCompatImpl(); 755 } else { 756 IMPL = new BaseViewCompatImpl(); 757 } 758 } 759 760 /** 761 * Check if this view can be scrolled horizontally in a certain direction. 762 * 763 * @param v The View against which to invoke the method. 764 * @param direction Negative to check scrolling left, positive to check scrolling right. 765 * @return true if this view can be scrolled in the specified direction, false otherwise. 766 */ 767 public static boolean canScrollHorizontally(View v, int direction) { 768 return IMPL.canScrollHorizontally(v, direction); 769 } 770 771 /** 772 * Check if this view can be scrolled vertically in a certain direction. 773 * 774 * @param v The View against which to invoke the method. 775 * @param direction Negative to check scrolling up, positive to check scrolling down. 776 * @return true if this view can be scrolled in the specified direction, false otherwise. 777 */ 778 public static boolean canScrollVertically(View v, int direction) { 779 return IMPL.canScrollVertically(v, direction); 780 } 781 782 /** 783 * Returns the over-scroll mode for this view. The result will be 784 * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS} 785 * (allow over-scrolling only if the view content is larger than the container), 786 * or {@link #OVER_SCROLL_NEVER}. 787 * 788 * @param v The View against which to invoke the method. 789 * @return This view's over-scroll mode. 790 */ 791 @OverScroll 792 public static int getOverScrollMode(View v) { 793 return IMPL.getOverScrollMode(v); 794 } 795 796 /** 797 * Set the over-scroll mode for this view. Valid over-scroll modes are 798 * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS} 799 * (allow over-scrolling only if the view content is larger than the container), 800 * or {@link #OVER_SCROLL_NEVER}. 801 * 802 * Setting the over-scroll mode of a view will have an effect only if the 803 * view is capable of scrolling. 804 * 805 * @param v The View against which to invoke the method. 806 * @param overScrollMode The new over-scroll mode for this view. 807 */ 808 public static void setOverScrollMode(View v, @OverScroll int overScrollMode) { 809 IMPL.setOverScrollMode(v, overScrollMode); 810 } 811 812 /** 813 * Called from {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} 814 * giving a chance to this View to populate the accessibility event with its 815 * text content. While this method is free to modify event 816 * attributes other than text content, doing so should normally be performed in 817 * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)}. 818 * <p> 819 * Example: Adding formatted date string to an accessibility event in addition 820 * to the text added by the super implementation: 821 * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 822 * super.onPopulateAccessibilityEvent(event); 823 * final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY; 824 * String selectedDateUtterance = DateUtils.formatDateTime(mContext, 825 * mCurrentDate.getTimeInMillis(), flags); 826 * event.getText().add(selectedDateUtterance); 827 * }</pre> 828 * <p> 829 * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling 830 * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its 831 * {@link android.view.View.AccessibilityDelegate#onPopulateAccessibilityEvent(View, 832 * AccessibilityEvent)} 833 * is responsible for handling this call. 834 * </p> 835 * <p class="note"><strong>Note:</strong> Always call the super implementation before adding 836 * information to the event, in case the default implementation has basic information to add. 837 * </p> 838 * 839 * @param v The View against which to invoke the method. 840 * @param event The accessibility event which to populate. 841 * 842 * @see View#sendAccessibilityEvent(int) 843 * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) 844 */ 845 public static void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) { 846 IMPL.onPopulateAccessibilityEvent(v, event); 847 } 848 849 /** 850 * Initializes an {@link AccessibilityEvent} with information about 851 * this View which is the event source. In other words, the source of 852 * an accessibility event is the view whose state change triggered firing 853 * the event. 854 * <p> 855 * Example: Setting the password property of an event in addition 856 * to properties set by the super implementation: 857 * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 858 * super.onInitializeAccessibilityEvent(event); 859 * event.setPassword(true); 860 * }</pre> 861 * <p> 862 * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling 863 * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its 864 * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityEvent(View, 865 * AccessibilityEvent)} 866 * is responsible for handling this call. 867 * </p> 868 * <p class="note"><strong>Note:</strong> Always call the super implementation before adding 869 * information to the event, in case the default implementation has basic information to add. 870 * </p> 871 * 872 * @param v The View against which to invoke the method. 873 * @param event The event to initialize. 874 * 875 * @see View#sendAccessibilityEvent(int) 876 * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) 877 */ 878 public static void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) { 879 IMPL.onInitializeAccessibilityEvent(v, event); 880 } 881 882 /** 883 * Initializes an {@link android.view.accessibility.AccessibilityNodeInfo} with information 884 * about this view. The base implementation sets: 885 * <ul> 886 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setParent(View)},</li> 887 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInParent(Rect)},</li> 888 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li> 889 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setPackageName(CharSequence)},</li> 890 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClassName(CharSequence)},</li> 891 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setContentDescription(CharSequence)},</li> 892 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setEnabled(boolean)},</li> 893 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClickable(boolean)},</li> 894 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocusable(boolean)},</li> 895 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocused(boolean)},</li> 896 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setLongClickable(boolean)},</li> 897 * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setSelected(boolean)},</li> 898 * </ul> 899 * <p> 900 * Subclasses should override this method, call the super implementation, 901 * and set additional attributes. 902 * </p> 903 * <p> 904 * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling 905 * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its 906 * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View, 907 * android.view.accessibility.AccessibilityNodeInfo)} 908 * is responsible for handling this call. 909 * </p> 910 * 911 * @param v The View against which to invoke the method. 912 * @param info The instance to initialize. 913 */ 914 public static void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) { 915 IMPL.onInitializeAccessibilityNodeInfo(v, info); 916 } 917 918 /** 919 * Sets a delegate for implementing accessibility support via compositon as 920 * opposed to inheritance. The delegate's primary use is for implementing 921 * backwards compatible widgets. For more details see 922 * {@link android.view.View.AccessibilityDelegate}. 923 * 924 * @param v The View against which to invoke the method. 925 * @param delegate The delegate instance. 926 * 927 * @see android.view.View.AccessibilityDelegate 928 */ 929 public static void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) { 930 IMPL.setAccessibilityDelegate(v, delegate); 931 } 932 933 /** 934 * Indicates whether the view is currently tracking transient state that the 935 * app should not need to concern itself with saving and restoring, but that 936 * the framework should take special note to preserve when possible. 937 * 938 * @param view View to check for transient state 939 * @return true if the view has transient state 940 */ 941 public static boolean hasTransientState(View view) { 942 return IMPL.hasTransientState(view); 943 } 944 945 /** 946 * Set whether this view is currently tracking transient state that the 947 * framework should attempt to preserve when possible. 948 * 949 * @param view View tracking transient state 950 * @param hasTransientState true if this view has transient state 951 */ 952 public static void setHasTransientState(View view, boolean hasTransientState) { 953 IMPL.setHasTransientState(view, hasTransientState); 954 } 955 956 /** 957 * <p>Cause an invalidate to happen on the next animation time step, typically the 958 * next display frame.</p> 959 * 960 * <p>This method can be invoked from outside of the UI thread 961 * only when this View is attached to a window.</p> 962 * 963 * @param view View to invalidate 964 */ 965 public static void postInvalidateOnAnimation(View view) { 966 IMPL.postInvalidateOnAnimation(view); 967 } 968 969 /** 970 * <p>Cause an invalidate of the specified area to happen on the next animation 971 * time step, typically the next display frame.</p> 972 * 973 * <p>This method can be invoked from outside of the UI thread 974 * only when this View is attached to a window.</p> 975 * 976 * @param view View to invalidate 977 * @param left The left coordinate of the rectangle to invalidate. 978 * @param top The top coordinate of the rectangle to invalidate. 979 * @param right The right coordinate of the rectangle to invalidate. 980 * @param bottom The bottom coordinate of the rectangle to invalidate. 981 */ 982 public static void postInvalidateOnAnimation(View view, int left, int top, 983 int right, int bottom) { 984 IMPL.postInvalidateOnAnimation(view, left, top, right, bottom); 985 } 986 987 /** 988 * <p>Causes the Runnable to execute on the next animation time step. 989 * The runnable will be run on the user interface thread.</p> 990 * 991 * <p>This method can be invoked from outside of the UI thread 992 * only when this View is attached to a window.</p> 993 * 994 * @param view View to post this Runnable to 995 * @param action The Runnable that will be executed. 996 */ 997 public static void postOnAnimation(View view, Runnable action) { 998 IMPL.postOnAnimation(view, action); 999 } 1000 1001 /** 1002 * <p>Causes the Runnable to execute on the next animation time step, 1003 * after the specified amount of time elapses. 1004 * The runnable will be run on the user interface thread.</p> 1005 * 1006 * <p>This method can be invoked from outside of the UI thread 1007 * only when this View is attached to a window.</p> 1008 * 1009 * @param view The view to post this Runnable to 1010 * @param action The Runnable that will be executed. 1011 * @param delayMillis The delay (in milliseconds) until the Runnable 1012 * will be executed. 1013 */ 1014 public static void postOnAnimationDelayed(View view, Runnable action, long delayMillis) { 1015 IMPL.postOnAnimationDelayed(view, action, delayMillis); 1016 } 1017 1018 /** 1019 * Gets the mode for determining whether this View is important for accessibility 1020 * which is if it fires accessibility events and if it is reported to 1021 * accessibility services that query the screen. 1022 * 1023 * @param view The view whose property to get. 1024 * @return The mode for determining whether a View is important for accessibility. 1025 * 1026 * @see #IMPORTANT_FOR_ACCESSIBILITY_YES 1027 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO 1028 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS 1029 * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO 1030 */ 1031 @ImportantForAccessibility 1032 public static int getImportantForAccessibility(View view) { 1033 return IMPL.getImportantForAccessibility(view); 1034 } 1035 1036 /** 1037 * Sets how to determine whether this view is important for accessibility 1038 * which is if it fires accessibility events and if it is reported to 1039 * accessibility services that query the screen. 1040 * <p> 1041 * <em>Note:</em> If the current paltform version does not support the 1042 * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} mode, then 1043 * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO} will be used as it is the 1044 * closest terms of semantics. 1045 * </p> 1046 * 1047 * @param view The view whose property to set. 1048 * @param mode How to determine whether this view is important for accessibility. 1049 * 1050 * @see #IMPORTANT_FOR_ACCESSIBILITY_YES 1051 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO 1052 * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS 1053 * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO 1054 */ 1055 public static void setImportantForAccessibility(View view, 1056 @ImportantForAccessibility int mode) { 1057 IMPL.setImportantForAccessibility(view, mode); 1058 } 1059 1060 /** 1061 * Performs the specified accessibility action on the view. For 1062 * possible accessibility actions look at {@link AccessibilityNodeInfoCompat}. 1063 * <p> 1064 * If an {@link AccessibilityDelegateCompat} has been specified via calling 1065 * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its 1066 * {@link AccessibilityDelegateCompat#performAccessibilityAction(View, int, Bundle)} 1067 * is responsible for handling this call. 1068 * </p> 1069 * 1070 * @param action The action to perform. 1071 * @param arguments Optional action arguments. 1072 * @return Whether the action was performed. 1073 */ 1074 public static boolean performAccessibilityAction(View view, int action, Bundle arguments) { 1075 return IMPL.performAccessibilityAction(view, action, arguments); 1076 } 1077 1078 /** 1079 * Gets the provider for managing a virtual view hierarchy rooted at this View 1080 * and reported to {@link android.accessibilityservice.AccessibilityService}s 1081 * that explore the window content. 1082 * <p> 1083 * If this method returns an instance, this instance is responsible for managing 1084 * {@link AccessibilityNodeInfoCompat}s describing the virtual sub-tree rooted at 1085 * this View including the one representing the View itself. Similarly the returned 1086 * instance is responsible for performing accessibility actions on any virtual 1087 * view or the root view itself. 1088 * </p> 1089 * <p> 1090 * If an {@link AccessibilityDelegateCompat} has been specified via calling 1091 * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its 1092 * {@link AccessibilityDelegateCompat#getAccessibilityNodeProvider(View)} 1093 * is responsible for handling this call. 1094 * </p> 1095 * 1096 * @param view The view whose property to get. 1097 * @return The provider. 1098 * 1099 * @see AccessibilityNodeProviderCompat 1100 */ 1101 public static AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) { 1102 return IMPL.getAccessibilityNodeProvider(view); 1103 } 1104 1105 /** 1106 * The opacity of the view. This is a value from 0 to 1, where 0 means the view is 1107 * completely transparent and 1 means the view is completely opaque. 1108 * 1109 * <p>By default this is 1.0f. Prior to API 11, the returned value is always 1.0f. 1110 * @return The opacity of the view. 1111 */ 1112 public static float getAlpha(View view) { 1113 return IMPL.getAlpha(view); 1114 } 1115 1116 /** 1117 * <p>Specifies the type of layer backing this view. The layer can be 1118 * {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or 1119 * {@link #LAYER_TYPE_HARDWARE hardware}.</p> 1120 * 1121 * <p>A layer is associated with an optional {@link android.graphics.Paint} 1122 * instance that controls how the layer is composed on screen. The following 1123 * properties of the paint are taken into account when composing the layer:</p> 1124 * <ul> 1125 * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li> 1126 * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li> 1127 * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li> 1128 * </ul> 1129 * 1130 * <p>If this view has an alpha value set to < 1.0 by calling 1131 * setAlpha(float), the alpha value of the layer's paint is replaced by 1132 * this view's alpha value. Calling setAlpha(float) is therefore 1133 * equivalent to setting a hardware layer on this view and providing a paint with 1134 * the desired alpha value.<p> 1135 * 1136 * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled}, 1137 * {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware} 1138 * for more information on when and how to use layers.</p> 1139 * 1140 * @param layerType The ype of layer to use with this view, must be one of 1141 * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or 1142 * {@link #LAYER_TYPE_HARDWARE} 1143 * @param paint The paint used to compose the layer. This argument is optional 1144 * and can be null. It is ignored when the layer type is 1145 * {@link #LAYER_TYPE_NONE} 1146 * 1147 * @param view View to set the layer type for 1148 * @param layerType The type of layer to use with this view, must be one of 1149 * {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or 1150 * {@link #LAYER_TYPE_HARDWARE} 1151 * @param paint The paint used to compose the layer. This argument is optional 1152 * and can be null. It is ignored when the layer type is 1153 * {@link #LAYER_TYPE_NONE} 1154 */ 1155 public static void setLayerType(View view, @LayerType int layerType, Paint paint) { 1156 IMPL.setLayerType(view, layerType, paint); 1157 } 1158 1159 /** 1160 * Indicates what type of layer is currently associated with this view. By default 1161 * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}. 1162 * Refer to the documentation of 1163 * {@link #setLayerType(android.view.View, int, android.graphics.Paint)} 1164 * for more information on the different types of layers. 1165 * 1166 * @param view The view to fetch the layer type from 1167 * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or 1168 * {@link #LAYER_TYPE_HARDWARE} 1169 * 1170 * @see #setLayerType(android.view.View, int, android.graphics.Paint) 1171 * @see #LAYER_TYPE_NONE 1172 * @see #LAYER_TYPE_SOFTWARE 1173 * @see #LAYER_TYPE_HARDWARE 1174 */ 1175 @LayerType 1176 public static int getLayerType(View view) { 1177 return IMPL.getLayerType(view); 1178 } 1179 1180 /** 1181 * Gets the id of a view for which a given view serves as a label for 1182 * accessibility purposes. 1183 * 1184 * @param view The view on which to invoke the corresponding method. 1185 * @return The labeled view id. 1186 */ 1187 public static int getLabelFor(View view) { 1188 return IMPL.getLabelFor(view); 1189 } 1190 1191 /** 1192 * Sets the id of a view for which a given view serves as a label for 1193 * accessibility purposes. 1194 * 1195 * @param view The view on which to invoke the corresponding method. 1196 * @param labeledId The labeled view id. 1197 */ 1198 public static void setLabelFor(View view, @IdRes int labeledId) { 1199 IMPL.setLabelFor(view, labeledId); 1200 } 1201 1202 /** 1203 * Updates the {@link Paint} object used with the current layer (used only if the current 1204 * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint 1205 * provided to {@link #setLayerType(android.view.View, int, android.graphics.Paint)} 1206 * will be used the next time the View is redrawn, but 1207 * {@link #setLayerPaint(android.view.View, android.graphics.Paint)} 1208 * must be called to ensure that the view gets redrawn immediately. 1209 * 1210 * <p>A layer is associated with an optional {@link android.graphics.Paint} 1211 * instance that controls how the layer is composed on screen. The following 1212 * properties of the paint are taken into account when composing the layer:</p> 1213 * <ul> 1214 * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li> 1215 * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li> 1216 * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li> 1217 * </ul> 1218 * 1219 * <p>If this view has an alpha value set to < 1.0 by calling 1220 * View#setAlpha(float), the alpha value of the layer's paint is replaced by 1221 * this view's alpha value. Calling View#setAlpha(float) is therefore 1222 * equivalent to setting a hardware layer on this view and providing a paint with 1223 * the desired alpha value.</p> 1224 * 1225 * @param view View to set a layer paint for 1226 * @param paint The paint used to compose the layer. This argument is optional 1227 * and can be null. It is ignored when the layer type is 1228 * {@link #LAYER_TYPE_NONE} 1229 * 1230 * @see #setLayerType(View, int, android.graphics.Paint) 1231 */ 1232 public static void setLayerPaint(View view, Paint paint) { 1233 IMPL.setLayerPaint(view, paint); 1234 } 1235 1236 /** 1237 * Returns the resolved layout direction for this view. 1238 * 1239 * @param view View to get layout direction for 1240 * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns 1241 * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL. 1242 * 1243 * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version 1244 * is lower than Jellybean MR1 (API 17) 1245 */ 1246 @ResolvedLayoutDirectionMode 1247 public static int getLayoutDirection(View view) { 1248 return IMPL.getLayoutDirection(view); 1249 } 1250 1251 /** 1252 * Set the layout direction for this view. This will propagate a reset of layout direction 1253 * resolution to the view's children and resolve layout direction for this view. 1254 * 1255 * @param view View to set layout direction for 1256 * @param layoutDirection the layout direction to set. Should be one of: 1257 * 1258 * {@link #LAYOUT_DIRECTION_LTR}, 1259 * {@link #LAYOUT_DIRECTION_RTL}, 1260 * {@link #LAYOUT_DIRECTION_INHERIT}, 1261 * {@link #LAYOUT_DIRECTION_LOCALE}. 1262 * 1263 * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution 1264 * proceeds up the parent chain of the view to get the value. If there is no parent, then it 1265 * will return the default {@link #LAYOUT_DIRECTION_LTR}. 1266 */ 1267 public static void setLayoutDirection(View view, @LayoutDirectionMode int layoutDirection) { 1268 IMPL.setLayoutDirection(view, layoutDirection); 1269 } 1270 1271 /** 1272 * Gets the parent for accessibility purposes. Note that the parent for 1273 * accessibility is not necessary the immediate parent. It is the first 1274 * predecessor that is important for accessibility. 1275 * 1276 * @param view View to retrieve parent for 1277 * @return The parent for use in accessibility inspection 1278 */ 1279 public static ViewParent getParentForAccessibility(View view) { 1280 return IMPL.getParentForAccessibility(view); 1281 } 1282 1283 /** 1284 * Indicates whether this View is opaque. An opaque View guarantees that it will 1285 * draw all the pixels overlapping its bounds using a fully opaque color. 1286 * 1287 * On API 7 and above this will call View's true isOpaque method. On previous platform 1288 * versions it will check the opacity of the view's background drawable if present. 1289 * 1290 * @return True if this View is guaranteed to be fully opaque, false otherwise. 1291 */ 1292 public static boolean isOpaque(View view) { 1293 return IMPL.isOpaque(view); 1294 } 1295 1296 /** 1297 * Utility to reconcile a desired size and state, with constraints imposed 1298 * by a MeasureSpec. Will take the desired size, unless a different size 1299 * is imposed by the constraints. The returned value is a compound integer, 1300 * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and 1301 * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting 1302 * size is smaller than the size the view wants to be. 1303 * 1304 * @param size How big the view wants to be 1305 * @param measureSpec Constraints imposed by the parent 1306 * @return Size information bit mask as defined by 1307 * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}. 1308 */ 1309 public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) { 1310 return IMPL.resolveSizeAndState(size, measureSpec, childMeasuredState); 1311 } 1312 1313 /** 1314 * Return the full width measurement information for this view as computed 1315 * by the most recent call to {@link android.view.View#measure(int, int)}. 1316 * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and 1317 * {@link #MEASURED_STATE_TOO_SMALL}. 1318 * This should be used during measurement and layout calculations only. Use 1319 * {@link android.view.View#getWidth()} to see how wide a view is after layout. 1320 * 1321 * @return The measured width of this view as a bit mask. 1322 */ 1323 public static int getMeasuredWidthAndState(View view) { 1324 return IMPL.getMeasuredWidthAndState(view); 1325 } 1326 1327 /** 1328 * Return the full height measurement information for this view as computed 1329 * by the most recent call to {@link android.view.View#measure(int, int)}. 1330 * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and 1331 * {@link #MEASURED_STATE_TOO_SMALL}. 1332 * This should be used during measurement and layout calculations only. Use 1333 * {@link android.view.View#getHeight()} to see how wide a view is after layout. 1334 * 1335 * @return The measured width of this view as a bit mask. 1336 */ 1337 public static int getMeasuredHeightAndState(View view) { 1338 return IMPL.getMeasuredHeightAndState(view); 1339 } 1340 1341 /** 1342 * Return only the state bits of {@link #getMeasuredWidthAndState} 1343 * and {@link #getMeasuredHeightAndState}, combined into one integer. 1344 * The width component is in the regular bits {@link #MEASURED_STATE_MASK} 1345 * and the height component is at the shifted bits 1346 * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}. 1347 */ 1348 public static int getMeasuredState(View view) { 1349 return IMPL.getMeasuredState(view); 1350 } 1351 1352 /** 1353 * Gets the live region mode for the specified View. 1354 * 1355 * @param view The view from which to obtain the live region mode 1356 * @return The live region mode for the view. 1357 * 1358 * @see ViewCompat#setAccessibilityLiveRegion(View, int) 1359 */ 1360 @AccessibilityLiveRegion 1361 public static int getAccessibilityLiveRegion(View view) { 1362 return IMPL.getAccessibilityLiveRegion(view); 1363 } 1364 1365 /** 1366 * Sets the live region mode for the specified view. This indicates to 1367 * accessibility services whether they should automatically notify the user 1368 * about changes to the view's content description or text, or to the 1369 * content descriptions or text of the view's children (where applicable). 1370 * <p> 1371 * For example, in a login screen with a TextView that displays an "incorrect 1372 * password" notification, that view should be marked as a live region with 1373 * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}. 1374 * <p> 1375 * To disable change notifications for this view, use 1376 * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region 1377 * mode for most views. 1378 * <p> 1379 * To indicate that the user should be notified of changes, use 1380 * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}. 1381 * <p> 1382 * If the view's changes should interrupt ongoing speech and notify the user 1383 * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}. 1384 * 1385 * @param view The view on which to set the live region mode 1386 * @param mode The live region mode for this view, one of: 1387 * <ul> 1388 * <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE} 1389 * <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE} 1390 * <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE} 1391 * </ul> 1392 */ 1393 public static void setAccessibilityLiveRegion(View view, @AccessibilityLiveRegion int mode) { 1394 IMPL.setAccessibilityLiveRegion(view, mode); 1395 } 1396 1397 /** 1398 * Returns the start padding of the specified view depending on its resolved layout direction. 1399 * If there are inset and enabled scrollbars, this value may include the space 1400 * required to display the scrollbars as well. 1401 * 1402 * @param view The view to get padding for 1403 * @return the start padding in pixels 1404 */ 1405 public static int getPaddingStart(View view) { 1406 return IMPL.getPaddingStart(view); 1407 } 1408 1409 /** 1410 * Returns the end padding of the specified view depending on its resolved layout direction. 1411 * If there are inset and enabled scrollbars, this value may include the space 1412 * required to display the scrollbars as well. 1413 * 1414 * @param view The view to get padding for 1415 * @return the end padding in pixels 1416 */ 1417 public static int getPaddingEnd(View view) { 1418 return IMPL.getPaddingEnd(view); 1419 } 1420 1421 /** 1422 * Sets the relative padding. The view may add on the space required to display 1423 * the scrollbars, depending on the style and visibility of the scrollbars. 1424 * So the values returned from {@link #getPaddingStart}, {@link View#getPaddingTop}, 1425 * {@link #getPaddingEnd} and {@link View#getPaddingBottom} may be different 1426 * from the values set in this call. 1427 * 1428 * @param view The view on which to set relative padding 1429 * @param start the start padding in pixels 1430 * @param top the top padding in pixels 1431 * @param end the end padding in pixels 1432 * @param bottom the bottom padding in pixels 1433 */ 1434 public static void setPaddingRelative(View view, int start, int top, int end, int bottom) { 1435 IMPL.setPaddingRelative(view, start, top, end, bottom); 1436 } 1437 1438 /** 1439 * Notify a view that it is being temporarily detached. 1440 */ 1441 public static void dispatchStartTemporaryDetach(View view) { 1442 IMPL.dispatchStartTemporaryDetach(view); 1443 } 1444 1445 /** 1446 * Notify a view that its temporary detach has ended; the view is now reattached. 1447 */ 1448 public static void dispatchFinishTemporaryDetach(View view) { 1449 IMPL.dispatchFinishTemporaryDetach(view); 1450 } 1451 1452 /** 1453 * The horizontal location of this view relative to its {@link View#getLeft() left} position. 1454 * This position is post-layout, in addition to wherever the object's 1455 * layout placed it. 1456 * 1457 * @return The horizontal position of this view relative to its left position, in pixels. 1458 */ 1459 public static float getTranslationX(View view) { 1460 return IMPL.getTranslationX(view); 1461 } 1462 1463 /** 1464 * The vertical location of this view relative to its {@link View#getTop() left} position. 1465 * This position is post-layout, in addition to wherever the object's 1466 * layout placed it. 1467 * 1468 * @return The vertical position of this view relative to its top position, in pixels. 1469 */ 1470 public static float getTranslationY(View view) { 1471 return IMPL.getTranslationY(view); 1472 } 1473 1474 /** 1475 * Returns the minimum width of the view. 1476 * 1477 * <p>Prior to API 16 this will return 0.</p> 1478 * 1479 * @return the minimum width the view will try to be. 1480 */ 1481 public static int getMinimumWidth(View view) { 1482 return IMPL.getMinimumWidth(view); 1483 } 1484 1485 /** 1486 * Returns the minimum height of the view. 1487 * 1488 * <p>Prior to API 16 this will return 0.</p> 1489 * 1490 * @return the minimum height the view will try to be. 1491 */ 1492 public static int getMinimumHeight(View view) { 1493 return IMPL.getMinimumHeight(view); 1494 } 1495} 1496