ViewConfiguration.java revision 7f9f99ea11051614a7727dfb9f9578b518e76e3c
1/* 2 * Copyright (C) 2006 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.view; 18 19import android.app.AppGlobals; 20import android.content.Context; 21import android.content.res.Configuration; 22import android.content.res.Resources; 23import android.os.RemoteException; 24import android.provider.Settings; 25import android.util.DisplayMetrics; 26import android.util.SparseArray; 27 28/** 29 * Contains methods to standard constants used in the UI for timeouts, sizes, and distances. 30 */ 31public class ViewConfiguration { 32 /** 33 * Expected bit depth of the display panel. 34 * 35 * @hide 36 */ 37 public static final float PANEL_BIT_DEPTH = 24; 38 39 /** 40 * Minimum alpha required for a view to draw. 41 * 42 * @hide 43 */ 44 public static final float ALPHA_THRESHOLD = 0.5f / PANEL_BIT_DEPTH; 45 /** 46 * @hide 47 */ 48 public static final float ALPHA_THRESHOLD_INT = 0x7f / PANEL_BIT_DEPTH; 49 50 /** 51 * Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in 52 * pixels 53 */ 54 private static final int SCROLL_BAR_SIZE = 10; 55 56 /** 57 * Duration of the fade when scrollbars fade away in milliseconds 58 */ 59 private static final int SCROLL_BAR_FADE_DURATION = 250; 60 61 /** 62 * Default delay before the scrollbars fade in milliseconds 63 */ 64 private static final int SCROLL_BAR_DEFAULT_DELAY = 300; 65 66 /** 67 * Defines the length of the fading edges in pixels 68 */ 69 private static final int FADING_EDGE_LENGTH = 12; 70 71 /** 72 * Defines the duration in milliseconds of the pressed state in child 73 * components. 74 */ 75 private static final int PRESSED_STATE_DURATION = 125; 76 77 /** 78 * Defines the default duration in milliseconds before a press turns into 79 * a long press 80 */ 81 private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500; 82 83 /** 84 * Defines the time between successive key repeats in milliseconds. 85 */ 86 private static final int KEY_REPEAT_DELAY = 50; 87 88 /** 89 * Defines the duration in milliseconds a user needs to hold down the 90 * appropriate button to bring up the global actions dialog (power off, 91 * lock screen, etc). 92 */ 93 private static final int GLOBAL_ACTIONS_KEY_TIMEOUT = 500; 94 95 /** 96 * Defines the duration in milliseconds we will wait to see if a touch event 97 * is a tap or a scroll. If the user does not move within this interval, it is 98 * considered to be a tap. 99 */ 100 private static final int TAP_TIMEOUT = 180; 101 102 /** 103 * Defines the duration in milliseconds we will wait to see if a touch event 104 * is a jump tap. If the user does not complete the jump tap within this interval, it is 105 * considered to be a tap. 106 */ 107 private static final int JUMP_TAP_TIMEOUT = 500; 108 109 /** 110 * Defines the duration in milliseconds between the first tap's up event and 111 * the second tap's down event for an interaction to be considered a 112 * double-tap. 113 */ 114 private static final int DOUBLE_TAP_TIMEOUT = 300; 115 116 /** 117 * Defines the maximum duration in milliseconds between a touch pad 118 * touch and release for a given touch to be considered a tap (click) as 119 * opposed to a hover movement gesture. 120 */ 121 private static final int HOVER_TAP_TIMEOUT = 150; 122 123 /** 124 * Defines the maximum distance in pixels that a touch pad touch can move 125 * before being released for it to be considered a tap (click) as opposed 126 * to a hover movement gesture. 127 */ 128 private static final int HOVER_TAP_SLOP = 20; 129 130 /** 131 * Defines the duration in milliseconds we want to display zoom controls in response 132 * to a user panning within an application. 133 */ 134 private static final int ZOOM_CONTROLS_TIMEOUT = 3000; 135 136 /** 137 * Inset in pixels to look for touchable content when the user touches the edge of the screen 138 */ 139 private static final int EDGE_SLOP = 12; 140 141 /** 142 * Distance a touch can wander before we think the user is scrolling in pixels 143 */ 144 private static final int TOUCH_SLOP = 16; 145 146 /** 147 * Distance a touch can wander before we think the user is attempting a paged scroll 148 * (in dips) 149 */ 150 private static final int PAGING_TOUCH_SLOP = TOUCH_SLOP * 2; 151 152 /** 153 * Distance between the first touch and second touch to still be considered a double tap 154 */ 155 private static final int DOUBLE_TAP_SLOP = 100; 156 157 /** 158 * Distance a touch needs to be outside of a window's bounds for it to 159 * count as outside for purposes of dismissing the window. 160 */ 161 private static final int WINDOW_TOUCH_SLOP = 16; 162 163 /** 164 * Minimum velocity to initiate a fling, as measured in pixels per second 165 */ 166 private static final int MINIMUM_FLING_VELOCITY = 50; 167 168 /** 169 * Maximum velocity to initiate a fling, as measured in pixels per second 170 */ 171 private static final int MAXIMUM_FLING_VELOCITY = 8000; 172 173 /** 174 * Distance between a touch up event denoting the end of a touch exploration 175 * gesture and the touch up event of a subsequent tap for the latter tap to be 176 * considered as a tap i.e. to perform a click. 177 */ 178 private static final int TOUCH_EXPLORATION_TAP_SLOP = 80; 179 180 /** 181 * Delay before dispatching a recurring accessibility event in milliseconds. 182 * This delay guarantees that a recurring event will be send at most once 183 * during the {@link #SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS} time 184 * frame. 185 */ 186 private static final long SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS = 400; 187 188 /** 189 * The maximum size of View's drawing cache, expressed in bytes. This size 190 * should be at least equal to the size of the screen in ARGB888 format. 191 */ 192 @Deprecated 193 private static final int MAXIMUM_DRAWING_CACHE_SIZE = 480 * 800 * 4; // ARGB8888 194 195 /** 196 * The coefficient of friction applied to flings/scrolls. 197 */ 198 private static final float SCROLL_FRICTION = 0.015f; 199 200 /** 201 * Max distance to overscroll for edge effects 202 */ 203 private static final int OVERSCROLL_DISTANCE = 0; 204 205 /** 206 * Max distance to overfling for edge effects 207 */ 208 private static final int OVERFLING_DISTANCE = 6; 209 210 private final int mEdgeSlop; 211 private final int mFadingEdgeLength; 212 private final int mMinimumFlingVelocity; 213 private final int mMaximumFlingVelocity; 214 private final int mScrollbarSize; 215 private final int mTouchSlop; 216 private final int mPagingTouchSlop; 217 private final int mDoubleTapSlop; 218 private final int mScaledTouchExplorationTapSlop; 219 private final int mWindowTouchSlop; 220 private final int mMaximumDrawingCacheSize; 221 private final int mOverscrollDistance; 222 private final int mOverflingDistance; 223 private final boolean mFadingMarqueeEnabled; 224 225 private boolean sHasPermanentMenuKey; 226 private boolean sHasPermanentMenuKeySet; 227 228 static final SparseArray<ViewConfiguration> sConfigurations = 229 new SparseArray<ViewConfiguration>(2); 230 231 /** 232 * @deprecated Use {@link android.view.ViewConfiguration#get(android.content.Context)} instead. 233 */ 234 @Deprecated 235 public ViewConfiguration() { 236 mEdgeSlop = EDGE_SLOP; 237 mFadingEdgeLength = FADING_EDGE_LENGTH; 238 mMinimumFlingVelocity = MINIMUM_FLING_VELOCITY; 239 mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY; 240 mScrollbarSize = SCROLL_BAR_SIZE; 241 mTouchSlop = TOUCH_SLOP; 242 mPagingTouchSlop = PAGING_TOUCH_SLOP; 243 mDoubleTapSlop = DOUBLE_TAP_SLOP; 244 mScaledTouchExplorationTapSlop = TOUCH_EXPLORATION_TAP_SLOP; 245 mWindowTouchSlop = WINDOW_TOUCH_SLOP; 246 //noinspection deprecation 247 mMaximumDrawingCacheSize = MAXIMUM_DRAWING_CACHE_SIZE; 248 mOverscrollDistance = OVERSCROLL_DISTANCE; 249 mOverflingDistance = OVERFLING_DISTANCE; 250 mFadingMarqueeEnabled = true; 251 } 252 253 /** 254 * Creates a new configuration for the specified context. The configuration depends on 255 * various parameters of the context, like the dimension of the display or the density 256 * of the display. 257 * 258 * @param context The application context used to initialize this view configuration. 259 * 260 * @see #get(android.content.Context) 261 * @see android.util.DisplayMetrics 262 */ 263 private ViewConfiguration(Context context) { 264 final Resources res = context.getResources(); 265 final DisplayMetrics metrics = res.getDisplayMetrics(); 266 final Configuration config = res.getConfiguration(); 267 final float density = metrics.density; 268 final float sizeAndDensity; 269 if (config.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_XLARGE)) { 270 sizeAndDensity = density * 1.5f; 271 } else { 272 sizeAndDensity = density; 273 } 274 275 mEdgeSlop = (int) (sizeAndDensity * EDGE_SLOP + 0.5f); 276 mFadingEdgeLength = (int) (sizeAndDensity * FADING_EDGE_LENGTH + 0.5f); 277 mMinimumFlingVelocity = (int) (density * MINIMUM_FLING_VELOCITY + 0.5f); 278 mMaximumFlingVelocity = (int) (density * MAXIMUM_FLING_VELOCITY + 0.5f); 279 mScrollbarSize = (int) (density * SCROLL_BAR_SIZE + 0.5f); 280 mTouchSlop = (int) (sizeAndDensity * TOUCH_SLOP + 0.5f); 281 mPagingTouchSlop = (int) (sizeAndDensity * PAGING_TOUCH_SLOP + 0.5f); 282 mDoubleTapSlop = (int) (sizeAndDensity * DOUBLE_TAP_SLOP + 0.5f); 283 mScaledTouchExplorationTapSlop = (int) (density * TOUCH_EXPLORATION_TAP_SLOP + 0.5f); 284 mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f); 285 286 // Size of the screen in bytes, in ARGB_8888 format 287 mMaximumDrawingCacheSize = 4 * metrics.widthPixels * metrics.heightPixels; 288 289 mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f); 290 mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f); 291 292 if (!sHasPermanentMenuKeySet) { 293 IWindowManager wm = Display.getWindowManager(); 294 try { 295 sHasPermanentMenuKey = wm.canStatusBarHide() && !res.getBoolean( 296 com.android.internal.R.bool.config_showNavigationBar); 297 sHasPermanentMenuKeySet = true; 298 } catch (RemoteException ex) { 299 sHasPermanentMenuKey = false; 300 } 301 } 302 303 mFadingMarqueeEnabled = res.getBoolean( 304 com.android.internal.R.bool.config_ui_enableFadingMarquee); 305 } 306 307 /** 308 * Returns a configuration for the specified context. The configuration depends on 309 * various parameters of the context, like the dimension of the display or the 310 * density of the display. 311 * 312 * @param context The application context used to initialize the view configuration. 313 */ 314 public static ViewConfiguration get(Context context) { 315 final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 316 final int density = (int) (100.0f * metrics.density); 317 318 ViewConfiguration configuration = sConfigurations.get(density); 319 if (configuration == null) { 320 configuration = new ViewConfiguration(context); 321 sConfigurations.put(density, configuration); 322 } 323 324 return configuration; 325 } 326 327 /** 328 * @return The width of the horizontal scrollbar and the height of the vertical 329 * scrollbar in pixels 330 * 331 * @deprecated Use {@link #getScaledScrollBarSize()} instead. 332 */ 333 @Deprecated 334 public static int getScrollBarSize() { 335 return SCROLL_BAR_SIZE; 336 } 337 338 /** 339 * @return The width of the horizontal scrollbar and the height of the vertical 340 * scrollbar in pixels 341 */ 342 public int getScaledScrollBarSize() { 343 return mScrollbarSize; 344 } 345 346 /** 347 * @return Duration of the fade when scrollbars fade away in milliseconds 348 */ 349 public static int getScrollBarFadeDuration() { 350 return SCROLL_BAR_FADE_DURATION; 351 } 352 353 /** 354 * @return Default delay before the scrollbars fade in milliseconds 355 */ 356 public static int getScrollDefaultDelay() { 357 return SCROLL_BAR_DEFAULT_DELAY; 358 } 359 360 /** 361 * @return the length of the fading edges in pixels 362 * 363 * @deprecated Use {@link #getScaledFadingEdgeLength()} instead. 364 */ 365 @Deprecated 366 public static int getFadingEdgeLength() { 367 return FADING_EDGE_LENGTH; 368 } 369 370 /** 371 * @return the length of the fading edges in pixels 372 */ 373 public int getScaledFadingEdgeLength() { 374 return mFadingEdgeLength; 375 } 376 377 /** 378 * @return the duration in milliseconds of the pressed state in child 379 * components. 380 */ 381 public static int getPressedStateDuration() { 382 return PRESSED_STATE_DURATION; 383 } 384 385 /** 386 * @return the duration in milliseconds before a press turns into 387 * a long press 388 */ 389 public static int getLongPressTimeout() { 390 return AppGlobals.getIntCoreSetting(Settings.Secure.LONG_PRESS_TIMEOUT, 391 DEFAULT_LONG_PRESS_TIMEOUT); 392 } 393 394 /** 395 * @return the time before the first key repeat in milliseconds. 396 */ 397 public static int getKeyRepeatTimeout() { 398 return getLongPressTimeout(); 399 } 400 401 /** 402 * @return the time between successive key repeats in milliseconds. 403 */ 404 public static int getKeyRepeatDelay() { 405 return KEY_REPEAT_DELAY; 406 } 407 408 /** 409 * @return the duration in milliseconds we will wait to see if a touch event 410 * is a tap or a scroll. If the user does not move within this interval, it is 411 * considered to be a tap. 412 */ 413 public static int getTapTimeout() { 414 return TAP_TIMEOUT; 415 } 416 417 /** 418 * @return the duration in milliseconds we will wait to see if a touch event 419 * is a jump tap. If the user does not move within this interval, it is 420 * considered to be a tap. 421 */ 422 public static int getJumpTapTimeout() { 423 return JUMP_TAP_TIMEOUT; 424 } 425 426 /** 427 * @return the duration in milliseconds between the first tap's up event and 428 * the second tap's down event for an interaction to be considered a 429 * double-tap. 430 */ 431 public static int getDoubleTapTimeout() { 432 return DOUBLE_TAP_TIMEOUT; 433 } 434 435 /** 436 * @return the maximum duration in milliseconds between a touch pad 437 * touch and release for a given touch to be considered a tap (click) as 438 * opposed to a hover movement gesture. 439 * @hide 440 */ 441 public static int getHoverTapTimeout() { 442 return HOVER_TAP_TIMEOUT; 443 } 444 445 /** 446 * @return the maximum distance in pixels that a touch pad touch can move 447 * before being released for it to be considered a tap (click) as opposed 448 * to a hover movement gesture. 449 * @hide 450 */ 451 public static int getHoverTapSlop() { 452 return HOVER_TAP_SLOP; 453 } 454 455 /** 456 * @return Inset in pixels to look for touchable content when the user touches the edge of the 457 * screen 458 * 459 * @deprecated Use {@link #getScaledEdgeSlop()} instead. 460 */ 461 @Deprecated 462 public static int getEdgeSlop() { 463 return EDGE_SLOP; 464 } 465 466 /** 467 * @return Inset in pixels to look for touchable content when the user touches the edge of the 468 * screen 469 */ 470 public int getScaledEdgeSlop() { 471 return mEdgeSlop; 472 } 473 474 /** 475 * @return Distance a touch can wander before we think the user is scrolling in pixels 476 * 477 * @deprecated Use {@link #getScaledTouchSlop()} instead. 478 */ 479 @Deprecated 480 public static int getTouchSlop() { 481 return TOUCH_SLOP; 482 } 483 484 /** 485 * @return Distance a touch can wander before we think the user is scrolling in pixels 486 */ 487 public int getScaledTouchSlop() { 488 return mTouchSlop; 489 } 490 491 /** 492 * @return Distance a touch can wander before we think the user is scrolling a full page 493 * in dips 494 */ 495 public int getScaledPagingTouchSlop() { 496 return mPagingTouchSlop; 497 } 498 499 /** 500 * @return Distance between the first touch and second touch to still be 501 * considered a double tap 502 * @deprecated Use {@link #getScaledDoubleTapSlop()} instead. 503 * @hide The only client of this should be GestureDetector, which needs this 504 * for clients that still use its deprecated constructor. 505 */ 506 @Deprecated 507 public static int getDoubleTapSlop() { 508 return DOUBLE_TAP_SLOP; 509 } 510 511 /** 512 * @return Distance between the first touch and second touch to still be 513 * considered a double tap 514 */ 515 public int getScaledDoubleTapSlop() { 516 return mDoubleTapSlop; 517 } 518 519 /** 520 * @return Distance between a touch up event denoting the end of a touch exploration 521 * gesture and the touch up event of a subsequent tap for the latter tap to be 522 * considered as a tap i.e. to perform a click. 523 * 524 * @hide 525 */ 526 public int getScaledTouchExplorationTapSlop() { 527 return mScaledTouchExplorationTapSlop; 528 } 529 530 /** 531 * Interval for dispatching a recurring accessibility event in milliseconds. 532 * This interval guarantees that a recurring event will be send at most once 533 * during the {@link #getSendRecurringAccessibilityEventsInterval()} time frame. 534 * 535 * @return The delay in milliseconds. 536 * 537 * @hide 538 */ 539 public static long getSendRecurringAccessibilityEventsInterval() { 540 return SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS; 541 } 542 543 /** 544 * @return Distance a touch must be outside the bounds of a window for it 545 * to be counted as outside the window for purposes of dismissing that 546 * window. 547 * 548 * @deprecated Use {@link #getScaledWindowTouchSlop()} instead. 549 */ 550 @Deprecated 551 public static int getWindowTouchSlop() { 552 return WINDOW_TOUCH_SLOP; 553 } 554 555 /** 556 * @return Distance a touch must be outside the bounds of a window for it 557 * to be counted as outside the window for purposes of dismissing that 558 * window. 559 */ 560 public int getScaledWindowTouchSlop() { 561 return mWindowTouchSlop; 562 } 563 564 /** 565 * @return Minimum velocity to initiate a fling, as measured in pixels per second. 566 * 567 * @deprecated Use {@link #getScaledMinimumFlingVelocity()} instead. 568 */ 569 @Deprecated 570 public static int getMinimumFlingVelocity() { 571 return MINIMUM_FLING_VELOCITY; 572 } 573 574 /** 575 * @return Minimum velocity to initiate a fling, as measured in pixels per second. 576 */ 577 public int getScaledMinimumFlingVelocity() { 578 return mMinimumFlingVelocity; 579 } 580 581 /** 582 * @return Maximum velocity to initiate a fling, as measured in pixels per second. 583 * 584 * @deprecated Use {@link #getScaledMaximumFlingVelocity()} instead. 585 */ 586 @Deprecated 587 public static int getMaximumFlingVelocity() { 588 return MAXIMUM_FLING_VELOCITY; 589 } 590 591 /** 592 * @return Maximum velocity to initiate a fling, as measured in pixels per second. 593 */ 594 public int getScaledMaximumFlingVelocity() { 595 return mMaximumFlingVelocity; 596 } 597 598 /** 599 * The maximum drawing cache size expressed in bytes. 600 * 601 * @return the maximum size of View's drawing cache expressed in bytes 602 * 603 * @deprecated Use {@link #getScaledMaximumDrawingCacheSize()} instead. 604 */ 605 @Deprecated 606 public static int getMaximumDrawingCacheSize() { 607 //noinspection deprecation 608 return MAXIMUM_DRAWING_CACHE_SIZE; 609 } 610 611 /** 612 * The maximum drawing cache size expressed in bytes. 613 * 614 * @return the maximum size of View's drawing cache expressed in bytes 615 */ 616 public int getScaledMaximumDrawingCacheSize() { 617 return mMaximumDrawingCacheSize; 618 } 619 620 /** 621 * @return The maximum distance a View should overscroll by when showing edge effects. 622 */ 623 public int getScaledOverscrollDistance() { 624 return mOverscrollDistance; 625 } 626 627 /** 628 * @return The maximum distance a View should overfling by when showing edge effects. 629 */ 630 public int getScaledOverflingDistance() { 631 return mOverflingDistance; 632 } 633 634 /** 635 * The amount of time that the zoom controls should be 636 * displayed on the screen expressed in milliseconds. 637 * 638 * @return the time the zoom controls should be visible expressed 639 * in milliseconds. 640 */ 641 public static long getZoomControlsTimeout() { 642 return ZOOM_CONTROLS_TIMEOUT; 643 } 644 645 /** 646 * The amount of time a user needs to press the relevant key to bring up 647 * the global actions dialog. 648 * 649 * @return how long a user needs to press the relevant key to bring up 650 * the global actions dialog. 651 */ 652 public static long getGlobalActionKeyTimeout() { 653 return GLOBAL_ACTIONS_KEY_TIMEOUT; 654 } 655 656 /** 657 * The amount of friction applied to scrolls and flings. 658 * 659 * @return A scalar dimensionless value representing the coefficient of 660 * friction. 661 */ 662 public static float getScrollFriction() { 663 return SCROLL_FRICTION; 664 } 665 666 /** 667 * Report if the device has a permanent menu key available to the user. 668 * 669 * <p>As of Android 3.0, devices may not have a permanent menu key available. 670 * Apps should use the action bar to present menu options to users. 671 * However, there are some apps where the action bar is inappropriate 672 * or undesirable. This method may be used to detect if a menu key is present. 673 * If not, applications should provide another on-screen affordance to access 674 * functionality. 675 * 676 * @return true if a permanent menu key is present, false otherwise. 677 */ 678 public boolean hasPermanentMenuKey() { 679 return sHasPermanentMenuKey; 680 } 681 682 /** 683 * @hide 684 * @return Whether or not marquee should use fading edges. 685 */ 686 public boolean isFadingMarqueeEnabled() { 687 return mFadingMarqueeEnabled; 688 } 689} 690