Loading core/java/android/view/View.java +60 −18 Original line number Diff line number Diff line Loading @@ -1495,6 +1495,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility */ static final int OPAQUE_MASK = 0x01800000; /** * Indicates a prepressed state; * the short time between ACTION_DOWN and recognizing * a 'real' press. Prepressed is used to recognize quick taps * even when they are shorter than ViewConfiguration.getTapTimeout(). * * @hide */ private static final int PREPRESSED = 0x02000000; /** * The parent this view is attached to. * {@hide} Loading Loading @@ -1722,6 +1732,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility private int mNextFocusDownId = View.NO_ID; private CheckForLongPress mPendingCheckForLongPress; private CheckForTap mPendingCheckForTap = null; private UnsetPressedState mUnsetPressedState; /** Loading Loading @@ -1763,6 +1775,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility */ private ViewTreeObserver mFloatingTreeObserver; /** * Cache the touch slop from the context that created the view. */ private int mTouchSlop; // Used for debug only static long sInstanceCount = 0; Loading @@ -1777,6 +1794,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mResources = context != null ? context.getResources() : null; mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED; ++sInstanceCount; mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } /** Loading Loading @@ -3951,7 +3969,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility (event.getRepeatCount() == 0)) { setPressed(true); if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { postCheckForLongClick(); postCheckForLongClick(0); } return true; } Loading Loading @@ -4174,7 +4192,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { switch (event.getAction()) { case MotionEvent.ACTION_UP: if ((mPrivateFlags & PRESSED) != 0) { boolean prepressed = (mPrivateFlags & PREPRESSED) != 0; if ((mPrivateFlags & PRESSED) != 0 || prepressed) { // take focus if we don't have it already and we should in // touch mode. boolean focusTaken = false; Loading @@ -4196,24 +4215,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mUnsetPressedState = new UnsetPressedState(); } if (!post(mUnsetPressedState)) { if (prepressed) { mPrivateFlags |= PRESSED; refreshDrawableState(); postDelayed(mUnsetPressedState, ViewConfiguration.getPressedStateDuration()); } else if (!post(mUnsetPressedState)) { // If the post failed, unpress right now mUnsetPressedState.run(); } removeTapCallback(); } break; case MotionEvent.ACTION_DOWN: mPrivateFlags |= PRESSED; refreshDrawableState(); if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { postCheckForLongClick(); if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } mPrivateFlags |= PREPRESSED; postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); break; case MotionEvent.ACTION_CANCEL: mPrivateFlags &= ~PRESSED; refreshDrawableState(); removeTapCallback(); break; case MotionEvent.ACTION_MOVE: Loading @@ -4221,25 +4247,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility final int y = (int) event.getY(); // Be lenient about moving outside of buttons int slop = ViewConfiguration.get(mContext).getScaledTouchSlop(); int slop = mTouchSlop; if ((x < 0 - slop) || (x >= getWidth() + slop) || (y < 0 - slop) || (y >= getHeight() + slop)) { // Outside button removeTapCallback(); if ((mPrivateFlags & PRESSED) != 0) { // Remove any future long press checks // Remove any future long press/tap checks removeLongPressCallback(); // Need to switch from pressed to not pressed mPrivateFlags &= ~PRESSED; refreshDrawableState(); } } else { // Inside button if ((mPrivateFlags & PRESSED) == 0) { // Need to switch from not pressed to pressed mPrivateFlags |= PRESSED; refreshDrawableState(); } } break; } Loading @@ -4258,6 +4278,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } } /** * Remove the tap detection timer. */ private void removeTapCallback() { if (mPendingCheckForTap != null) { mPrivateFlags &= ~PREPRESSED; removeCallbacks(mPendingCheckForTap); } } /** * Cancels a pending long press. Your subclass can use this if you * want the context menu to come up if the user presses and holds Loading Loading @@ -8427,14 +8457,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } } private void postCheckForLongClick() { private void postCheckForLongClick(int delayOffset) { mHasPerformedLongPress = false; if (mPendingCheckForLongPress == null) { mPendingCheckForLongPress = new CheckForLongPress(); } mPendingCheckForLongPress.rememberWindowAttachCount(); postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout()); postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout() - delayOffset); } private static int[] stateSetUnion(final int[] stateSet1, Loading Loading @@ -8612,6 +8643,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } } private final class CheckForTap implements Runnable { public void run() { mPrivateFlags &= ~PREPRESSED; mPrivateFlags |= PRESSED; refreshDrawableState(); if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { postCheckForLongClick(ViewConfiguration.getTapTimeout()); } } } /** * Interface definition for a callback to be invoked when a key event is * dispatched to this view. The callback will be invoked before the key Loading core/java/android/view/ViewConfiguration.java +2 −2 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ public class ViewConfiguration { * Defines the duration in milliseconds of the pressed state in child * components. */ private static final int PRESSED_STATE_DURATION = 85; private static final int PRESSED_STATE_DURATION = 125; /** * Defines the duration in milliseconds before a press turns into Loading @@ -69,7 +69,7 @@ public class ViewConfiguration { * is a tap or a scroll. If the user does not move within this interval, it is * considered to be a tap. */ private static final int TAP_TIMEOUT = 100; private static final int TAP_TIMEOUT = 115; /** * Defines the duration in milliseconds we will wait to see if a touch event Loading Loading
core/java/android/view/View.java +60 −18 Original line number Diff line number Diff line Loading @@ -1495,6 +1495,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility */ static final int OPAQUE_MASK = 0x01800000; /** * Indicates a prepressed state; * the short time between ACTION_DOWN and recognizing * a 'real' press. Prepressed is used to recognize quick taps * even when they are shorter than ViewConfiguration.getTapTimeout(). * * @hide */ private static final int PREPRESSED = 0x02000000; /** * The parent this view is attached to. * {@hide} Loading Loading @@ -1722,6 +1732,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility private int mNextFocusDownId = View.NO_ID; private CheckForLongPress mPendingCheckForLongPress; private CheckForTap mPendingCheckForTap = null; private UnsetPressedState mUnsetPressedState; /** Loading Loading @@ -1763,6 +1775,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility */ private ViewTreeObserver mFloatingTreeObserver; /** * Cache the touch slop from the context that created the view. */ private int mTouchSlop; // Used for debug only static long sInstanceCount = 0; Loading @@ -1777,6 +1794,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mResources = context != null ? context.getResources() : null; mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED; ++sInstanceCount; mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } /** Loading Loading @@ -3951,7 +3969,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility (event.getRepeatCount() == 0)) { setPressed(true); if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { postCheckForLongClick(); postCheckForLongClick(0); } return true; } Loading Loading @@ -4174,7 +4192,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { switch (event.getAction()) { case MotionEvent.ACTION_UP: if ((mPrivateFlags & PRESSED) != 0) { boolean prepressed = (mPrivateFlags & PREPRESSED) != 0; if ((mPrivateFlags & PRESSED) != 0 || prepressed) { // take focus if we don't have it already and we should in // touch mode. boolean focusTaken = false; Loading @@ -4196,24 +4215,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mUnsetPressedState = new UnsetPressedState(); } if (!post(mUnsetPressedState)) { if (prepressed) { mPrivateFlags |= PRESSED; refreshDrawableState(); postDelayed(mUnsetPressedState, ViewConfiguration.getPressedStateDuration()); } else if (!post(mUnsetPressedState)) { // If the post failed, unpress right now mUnsetPressedState.run(); } removeTapCallback(); } break; case MotionEvent.ACTION_DOWN: mPrivateFlags |= PRESSED; refreshDrawableState(); if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { postCheckForLongClick(); if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } mPrivateFlags |= PREPRESSED; postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); break; case MotionEvent.ACTION_CANCEL: mPrivateFlags &= ~PRESSED; refreshDrawableState(); removeTapCallback(); break; case MotionEvent.ACTION_MOVE: Loading @@ -4221,25 +4247,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility final int y = (int) event.getY(); // Be lenient about moving outside of buttons int slop = ViewConfiguration.get(mContext).getScaledTouchSlop(); int slop = mTouchSlop; if ((x < 0 - slop) || (x >= getWidth() + slop) || (y < 0 - slop) || (y >= getHeight() + slop)) { // Outside button removeTapCallback(); if ((mPrivateFlags & PRESSED) != 0) { // Remove any future long press checks // Remove any future long press/tap checks removeLongPressCallback(); // Need to switch from pressed to not pressed mPrivateFlags &= ~PRESSED; refreshDrawableState(); } } else { // Inside button if ((mPrivateFlags & PRESSED) == 0) { // Need to switch from not pressed to pressed mPrivateFlags |= PRESSED; refreshDrawableState(); } } break; } Loading @@ -4258,6 +4278,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } } /** * Remove the tap detection timer. */ private void removeTapCallback() { if (mPendingCheckForTap != null) { mPrivateFlags &= ~PREPRESSED; removeCallbacks(mPendingCheckForTap); } } /** * Cancels a pending long press. Your subclass can use this if you * want the context menu to come up if the user presses and holds Loading Loading @@ -8427,14 +8457,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } } private void postCheckForLongClick() { private void postCheckForLongClick(int delayOffset) { mHasPerformedLongPress = false; if (mPendingCheckForLongPress == null) { mPendingCheckForLongPress = new CheckForLongPress(); } mPendingCheckForLongPress.rememberWindowAttachCount(); postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout()); postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout() - delayOffset); } private static int[] stateSetUnion(final int[] stateSet1, Loading Loading @@ -8612,6 +8643,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } } private final class CheckForTap implements Runnable { public void run() { mPrivateFlags &= ~PREPRESSED; mPrivateFlags |= PRESSED; refreshDrawableState(); if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { postCheckForLongClick(ViewConfiguration.getTapTimeout()); } } } /** * Interface definition for a callback to be invoked when a key event is * dispatched to this view. The callback will be invoked before the key Loading
core/java/android/view/ViewConfiguration.java +2 −2 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ public class ViewConfiguration { * Defines the duration in milliseconds of the pressed state in child * components. */ private static final int PRESSED_STATE_DURATION = 85; private static final int PRESSED_STATE_DURATION = 125; /** * Defines the duration in milliseconds before a press turns into Loading @@ -69,7 +69,7 @@ public class ViewConfiguration { * is a tap or a scroll. If the user does not move within this interval, it is * considered to be a tap. */ private static final int TAP_TIMEOUT = 100; private static final int TAP_TIMEOUT = 115; /** * Defines the duration in milliseconds we will wait to see if a touch event Loading