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 17 package android.view; 18 19 import android.content.Context; 20 import android.util.DisplayMetrics; 21 import android.util.SparseArray; 22 23 /** 24 * Contains methods to standard constants used in the UI for timeouts, sizes, and distances. 25 */ 26 public class ViewConfiguration { 27 /** 28 * Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in 29 * pixels 30 */ 31 private static final int SCROLL_BAR_SIZE = 10; 32 33 /** 34 * Duration of the fade when scrollbars fade away in milliseconds 35 */ 36 private static final int SCROLL_BAR_FADE_DURATION = 250; 37 38 /** 39 * Default delay before the scrollbars fade in milliseconds 40 */ 41 private static final int SCROLL_BAR_DEFAULT_DELAY = 300; 42 43 /** 44 * Defines the length of the fading edges in pixels 45 */ 46 private static final int FADING_EDGE_LENGTH = 12; 47 48 /** 49 * Defines the duration in milliseconds of the pressed state in child 50 * components. 51 */ 52 private static final int PRESSED_STATE_DURATION = 125; 53 54 /** 55 * Defines the duration in milliseconds before a press turns into 56 * a long press 57 */ 58 private static final int LONG_PRESS_TIMEOUT = 500; 59 60 /** 61 * Defines the duration in milliseconds a user needs to hold down the 62 * appropriate button to bring up the global actions dialog (power off, 63 * lock screen, etc). 64 */ 65 private static final int GLOBAL_ACTIONS_KEY_TIMEOUT = 500; 66 67 /** 68 * Defines the duration in milliseconds we will wait to see if a touch event 69 * is a tap or a scroll. If the user does not move within this interval, it is 70 * considered to be a tap. 71 */ 72 private static final int TAP_TIMEOUT = 115; 73 74 /** 75 * Defines the duration in milliseconds we will wait to see if a touch event 76 * is a jump tap. If the user does not complete the jump tap within this interval, it is 77 * considered to be a tap. 78 */ 79 private static final int JUMP_TAP_TIMEOUT = 500; 80 81 /** 82 * Defines the duration in milliseconds between the first tap's up event and 83 * the second tap's down event for an interaction to be considered a 84 * double-tap. 85 */ 86 private static final int DOUBLE_TAP_TIMEOUT = 300; 87 88 /** 89 * Defines the duration in milliseconds we want to display zoom controls in response 90 * to a user panning within an application. 91 */ 92 private static final int ZOOM_CONTROLS_TIMEOUT = 3000; 93 94 /** 95 * Inset in pixels to look for touchable content when the user touches the edge of the screen 96 */ 97 private static final int EDGE_SLOP = 12; 98 99 /** 100 * Distance a touch can wander before we think the user is scrolling in pixels 101 */ 102 private static final int TOUCH_SLOP = 16; 103 104 /** 105 * Distance a touch can wander before we think the user is attempting a paged scroll 106 * (in dips) 107 */ 108 private static final int PAGING_TOUCH_SLOP = TOUCH_SLOP * 2; 109 110 /** 111 * Distance between the first touch and second touch to still be considered a double tap 112 */ 113 private static final int DOUBLE_TAP_SLOP = 100; 114 115 /** 116 * Distance a touch needs to be outside of a window's bounds for it to 117 * count as outside for purposes of dismissing the window. 118 */ 119 private static final int WINDOW_TOUCH_SLOP = 16; 120 121 /** 122 * Minimum velocity to initiate a fling, as measured in pixels per second 123 */ 124 private static final int MINIMUM_FLING_VELOCITY = 50; 125 126 /** 127 * Maximum velocity to initiate a fling, as measured in pixels per second 128 */ 129 private static final int MAXIMUM_FLING_VELOCITY = 4000; 130 131 /** 132 * The maximum size of View's drawing cache, expressed in bytes. This size 133 * should be at least equal to the size of the screen in ARGB888 format. 134 */ 135 @Deprecated 136 private static final int MAXIMUM_DRAWING_CACHE_SIZE = 320 * 480 * 4; // HVGA screen, ARGB8888 137 138 /** 139 * The coefficient of friction applied to flings/scrolls. 140 */ 141 private static float SCROLL_FRICTION = 0.015f; 142 143 /** 144 * Max distance to overscroll for edge effects 145 */ 146 private static final int OVERSCROLL_DISTANCE = 0; 147 148 /** 149 * Max distance to overfling for edge effects 150 */ 151 private static final int OVERFLING_DISTANCE = 4; 152 153 private final int mEdgeSlop; 154 private final int mFadingEdgeLength; 155 private final int mMinimumFlingVelocity; 156 private final int mMaximumFlingVelocity; 157 private final int mScrollbarSize; 158 private final int mTouchSlop; 159 private final int mPagingTouchSlop; 160 private final int mDoubleTapSlop; 161 private final int mWindowTouchSlop; 162 private final int mMaximumDrawingCacheSize; 163 private final int mOverscrollDistance; 164 private final int mOverflingDistance; 165 166 private static final SparseArray<ViewConfiguration> sConfigurations = 167 new SparseArray<ViewConfiguration>(2); 168 169 /** 170 * @deprecated Use {@link android.view.ViewConfiguration#get(android.content.Context)} instead. 171 */ 172 @Deprecated 173 public ViewConfiguration() { 174 mEdgeSlop = EDGE_SLOP; 175 mFadingEdgeLength = FADING_EDGE_LENGTH; 176 mMinimumFlingVelocity = MINIMUM_FLING_VELOCITY; 177 mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY; 178 mScrollbarSize = SCROLL_BAR_SIZE; 179 mTouchSlop = TOUCH_SLOP; 180 mPagingTouchSlop = PAGING_TOUCH_SLOP; 181 mDoubleTapSlop = DOUBLE_TAP_SLOP; 182 mWindowTouchSlop = WINDOW_TOUCH_SLOP; 183 //noinspection deprecation 184 mMaximumDrawingCacheSize = MAXIMUM_DRAWING_CACHE_SIZE; 185 mOverscrollDistance = OVERSCROLL_DISTANCE; 186 mOverflingDistance = OVERFLING_DISTANCE; 187 } 188 189 /** 190 * Creates a new configuration for the specified context. The configuration depends on 191 * various parameters of the context, like the dimension of the display or the density 192 * of the display. 193 * 194 * @param context The application context used to initialize this view configuration. 195 * 196 * @see #get(android.content.Context) 197 * @see android.util.DisplayMetrics 198 */ 199 private ViewConfiguration(Context context) { 200 final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 201 final float density = metrics.density; 202 203 mEdgeSlop = (int) (density * EDGE_SLOP + 0.5f); 204 mFadingEdgeLength = (int) (density * FADING_EDGE_LENGTH + 0.5f); 205 mMinimumFlingVelocity = (int) (density * MINIMUM_FLING_VELOCITY + 0.5f); 206 mMaximumFlingVelocity = (int) (density * MAXIMUM_FLING_VELOCITY + 0.5f); 207 mScrollbarSize = (int) (density * SCROLL_BAR_SIZE + 0.5f); 208 mTouchSlop = (int) (density * TOUCH_SLOP + 0.5f); 209 mPagingTouchSlop = (int) (density * PAGING_TOUCH_SLOP + 0.5f); 210 mDoubleTapSlop = (int) (density * DOUBLE_TAP_SLOP + 0.5f); 211 mWindowTouchSlop = (int) (density * WINDOW_TOUCH_SLOP + 0.5f); 212 213 // Size of the screen in bytes, in ARGB_8888 format 214 mMaximumDrawingCacheSize = 4 * metrics.widthPixels * metrics.heightPixels; 215 216 mOverscrollDistance = (int) (density * OVERSCROLL_DISTANCE + 0.5f); 217 mOverflingDistance = (int) (density * OVERFLING_DISTANCE + 0.5f); 218 } 219 220 /** 221 * Returns a configuration for the specified context. The configuration depends on 222 * various parameters of the context, like the dimension of the display or the 223 * density of the display. 224 * 225 * @param context The application context used to initialize the view configuration. 226 */ 227 public static ViewConfiguration get(Context context) { 228 final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 229 final int density = (int) (100.0f * metrics.density); 230 231 ViewConfiguration configuration = sConfigurations.get(density); 232 if (configuration == null) { 233 configuration = new ViewConfiguration(context); 234 sConfigurations.put(density, configuration); 235 } 236 237 return configuration; 238 } 239 240 /** 241 * @return The width of the horizontal scrollbar and the height of the vertical 242 * scrollbar in pixels 243 * 244 * @deprecated Use {@link #getScaledScrollBarSize()} instead. 245 */ 246 @Deprecated 247 public static int getScrollBarSize() { 248 return SCROLL_BAR_SIZE; 249 } 250 251 /** 252 * @return The width of the horizontal scrollbar and the height of the vertical 253 * scrollbar in pixels 254 */ 255 public int getScaledScrollBarSize() { 256 return mScrollbarSize; 257 } 258 259 /** 260 * @return Duration of the fade when scrollbars fade away in milliseconds 261 */ 262 public static int getScrollBarFadeDuration() { 263 return SCROLL_BAR_FADE_DURATION; 264 } 265 266 /** 267 * @return Default delay before the scrollbars fade in milliseconds 268 */ 269 public static int getScrollDefaultDelay() { 270 return SCROLL_BAR_DEFAULT_DELAY; 271 } 272 273 /** 274 * @return the length of the fading edges in pixels 275 * 276 * @deprecated Use {@link #getScaledFadingEdgeLength()} instead. 277 */ 278 @Deprecated 279 public static int getFadingEdgeLength() { 280 return FADING_EDGE_LENGTH; 281 } 282 283 /** 284 * @return the length of the fading edges in pixels 285 */ 286 public int getScaledFadingEdgeLength() { 287 return mFadingEdgeLength; 288 } 289 290 /** 291 * @return the duration in milliseconds of the pressed state in child 292 * components. 293 */ 294 public static int getPressedStateDuration() { 295 return PRESSED_STATE_DURATION; 296 } 297 298 /** 299 * @return the duration in milliseconds before a press turns into 300 * a long press 301 */ 302 public static int getLongPressTimeout() { 303 return LONG_PRESS_TIMEOUT; 304 } 305 306 /** 307 * @return the duration in milliseconds we will wait to see if a touch event 308 * is a tap or a scroll. If the user does not move within this interval, it is 309 * considered to be a tap. 310 */ 311 public static int getTapTimeout() { 312 return TAP_TIMEOUT; 313 } 314 315 /** 316 * @return the duration in milliseconds we will wait to see if a touch event 317 * is a jump tap. If the user does not move within this interval, it is 318 * considered to be a tap. 319 */ 320 public static int getJumpTapTimeout() { 321 return JUMP_TAP_TIMEOUT; 322 } 323 324 /** 325 * @return the duration in milliseconds between the first tap's up event and 326 * the second tap's down event for an interaction to be considered a 327 * double-tap. 328 */ 329 public static int getDoubleTapTimeout() { 330 return DOUBLE_TAP_TIMEOUT; 331 } 332 333 /** 334 * @return Inset in pixels to look for touchable content when the user touches the edge of the 335 * screen 336 * 337 * @deprecated Use {@link #getScaledEdgeSlop()} instead. 338 */ 339 @Deprecated 340 public static int getEdgeSlop() { 341 return EDGE_SLOP; 342 } 343 344 /** 345 * @return Inset in pixels to look for touchable content when the user touches the edge of the 346 * screen 347 */ 348 public int getScaledEdgeSlop() { 349 return mEdgeSlop; 350 } 351 352 /** 353 * @return Distance a touch can wander before we think the user is scrolling in pixels 354 * 355 * @deprecated Use {@link #getScaledTouchSlop()} instead. 356 */ 357 @Deprecated 358 public static int getTouchSlop() { 359 return TOUCH_SLOP; 360 } 361 362 /** 363 * @return Distance a touch can wander before we think the user is scrolling in pixels 364 */ 365 public int getScaledTouchSlop() { 366 return mTouchSlop; 367 } 368 369 /** 370 * @return Distance a touch can wander before we think the user is scrolling a full page 371 * in dips 372 */ 373 public int getScaledPagingTouchSlop() { 374 return mPagingTouchSlop; 375 } 376 377 /** 378 * @return Distance between the first touch and second touch to still be 379 * considered a double tap 380 * @deprecated Use {@link #getScaledDoubleTapSlop()} instead. 381 * @hide The only client of this should be GestureDetector, which needs this 382 * for clients that still use its deprecated constructor. 383 */ 384 @Deprecated 385 public static int getDoubleTapSlop() { 386 return DOUBLE_TAP_SLOP; 387 } 388 389 /** 390 * @return Distance between the first touch and second touch to still be 391 * considered a double tap 392 */ 393 public int getScaledDoubleTapSlop() { 394 return mDoubleTapSlop; 395 } 396 397 /** 398 * @return Distance a touch must be outside the bounds of a window for it 399 * to be counted as outside the window for purposes of dismissing that 400 * window. 401 * 402 * @deprecated Use {@link #getScaledWindowTouchSlop()} instead. 403 */ 404 @Deprecated 405 public static int getWindowTouchSlop() { 406 return WINDOW_TOUCH_SLOP; 407 } 408 409 /** 410 * @return Distance a touch must be outside the bounds of a window for it 411 * to be counted as outside the window for purposes of dismissing that 412 * window. 413 */ 414 public int getScaledWindowTouchSlop() { 415 return mWindowTouchSlop; 416 } 417 418 /** 419 * @return Minimum velocity to initiate a fling, as measured in pixels per second. 420 * 421 * @deprecated Use {@link #getScaledMinimumFlingVelocity()} instead. 422 */ 423 @Deprecated 424 public static int getMinimumFlingVelocity() { 425 return MINIMUM_FLING_VELOCITY; 426 } 427 428 /** 429 * @return Minimum velocity to initiate a fling, as measured in pixels per second. 430 */ 431 public int getScaledMinimumFlingVelocity() { 432 return mMinimumFlingVelocity; 433 } 434 435 /** 436 * @return Maximum velocity to initiate a fling, as measured in pixels per second. 437 * 438 * @deprecated Use {@link #getScaledMaximumFlingVelocity()} instead. 439 */ 440 @Deprecated 441 public static int getMaximumFlingVelocity() { 442 return MAXIMUM_FLING_VELOCITY; 443 } 444 445 /** 446 * @return Maximum velocity to initiate a fling, as measured in pixels per second. 447 */ 448 public int getScaledMaximumFlingVelocity() { 449 return mMaximumFlingVelocity; 450 } 451 452 /** 453 * The maximum drawing cache size expressed in bytes. 454 * 455 * @return the maximum size of View's drawing cache expressed in bytes 456 * 457 * @deprecated Use {@link #getScaledMaximumDrawingCacheSize()} instead. 458 */ 459 @Deprecated 460 public static int getMaximumDrawingCacheSize() { 461 //noinspection deprecation 462 return MAXIMUM_DRAWING_CACHE_SIZE; 463 } 464 465 /** 466 * The maximum drawing cache size expressed in bytes. 467 * 468 * @return the maximum size of View's drawing cache expressed in bytes 469 */ 470 public int getScaledMaximumDrawingCacheSize() { 471 return mMaximumDrawingCacheSize; 472 } 473 474 /** 475 * @return The maximum distance a View should overscroll by when showing edge effects. 476 */ 477 public int getScaledOverscrollDistance() { 478 return mOverscrollDistance; 479 } 480 481 /** 482 * @return The maximum distance a View should overfling by when showing edge effects. 483 */ 484 public int getScaledOverflingDistance() { 485 return mOverflingDistance; 486 } 487 488 /** 489 * The amount of time that the zoom controls should be 490 * displayed on the screen expressed in milliseconds. 491 * 492 * @return the time the zoom controls should be visible expressed 493 * in milliseconds. 494 */ 495 public static long getZoomControlsTimeout() { 496 return ZOOM_CONTROLS_TIMEOUT; 497 } 498 499 /** 500 * The amount of time a user needs to press the relevant key to bring up 501 * the global actions dialog. 502 * 503 * @return how long a user needs to press the relevant key to bring up 504 * the global actions dialog. 505 */ 506 public static long getGlobalActionKeyTimeout() { 507 return GLOBAL_ACTIONS_KEY_TIMEOUT; 508 } 509 510 /** 511 * The amount of friction applied to scrolls and flings. 512 * 513 * @return A scalar dimensionless value representing the coefficient of 514 * friction. 515 */ 516 public static float getScrollFriction() { 517 return SCROLL_FRICTION; 518 } 519 } 520