Merge "Allow medium-long-press to initiate drag-to-open menus" into lmp-dev

This commit is contained in:
Alan Viverette
2014-07-24 03:20:55 +00:00
committed by Android (Google) Code Review

View File

@@ -1186,15 +1186,27 @@ public class ListPopupWindow {
/** Timeout before disallowing intercept on the source's parent. */
private final int mTapTimeout;
/** Timeout before accepting a long-press to start forwarding. */
private final int mLongPressTimeout;
/** Source view from which events are forwarded. */
private final View mSrc;
/** Runnable used to prevent conflicts with scrolling parents. */
private Runnable mDisallowIntercept;
/** Runnable used to trigger forwarding on long-press. */
private Runnable mTriggerLongPress;
/** Whether this listener is currently forwarding touch events. */
private boolean mForwarding;
/**
* Whether forwarding was initiated by a long-press. If so, we won't
* force the window to dismiss when the touch stream ends.
*/
private boolean mWasLongPress;
/** The id of the first pointer down in the current event stream. */
private int mActivePointerId;
@@ -1203,6 +1215,9 @@ public class ListPopupWindow {
mScaledTouchSlop = ViewConfiguration.get(src.getContext()).getScaledTouchSlop();
mTapTimeout = ViewConfiguration.getTapTimeout();
// Use a medium-press timeout. Halfway between tap and long-press.
mLongPressTimeout = (mTapTimeout + ViewConfiguration.getLongPressTimeout()) / 2;
src.addOnAttachStateChangeListener(this);
}
@@ -1223,7 +1238,14 @@ public class ListPopupWindow {
final boolean wasForwarding = mForwarding;
final boolean forwarding;
if (wasForwarding) {
forwarding = onTouchForwarded(event) || !onForwardingStopped();
if (mWasLongPress) {
// If we started forwarding as a result of a long-press,
// just silently stop forwarding events so that the window
// stays open.
forwarding = onTouchForwarded(event);
} else {
forwarding = onTouchForwarded(event) || !onForwardingStopped();
}
} else {
forwarding = onTouchObserved(event) && onForwardingStarted();
@@ -1305,21 +1327,29 @@ public class ListPopupWindow {
switch (actionMasked) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = srcEvent.getPointerId(0);
mWasLongPress = false;
if (mDisallowIntercept == null) {
mDisallowIntercept = new DisallowIntercept();
}
src.postDelayed(mDisallowIntercept, mTapTimeout);
if (mTriggerLongPress == null) {
mTriggerLongPress = new TriggerLongPress();
}
src.postDelayed(mTriggerLongPress, mLongPressTimeout);
break;
case MotionEvent.ACTION_MOVE:
final int activePointerIndex = srcEvent.findPointerIndex(mActivePointerId);
if (activePointerIndex >= 0) {
final float x = srcEvent.getX(activePointerIndex);
final float y = srcEvent.getY(activePointerIndex);
// Has the pointer has moved outside of the view?
if (!src.pointInView(x, y, mScaledTouchSlop)) {
// The pointer has moved outside of the view.
if (mDisallowIntercept != null) {
src.removeCallbacks(mDisallowIntercept);
}
clearCallbacks();
// Don't let the parent intercept our events.
src.getParent().requestDisallowInterceptTouchEvent(true);
return true;
}
@@ -1327,15 +1357,48 @@ public class ListPopupWindow {
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (mDisallowIntercept != null) {
src.removeCallbacks(mDisallowIntercept);
}
clearCallbacks();
break;
}
return false;
}
private void clearCallbacks() {
if (mTriggerLongPress != null) {
mSrc.removeCallbacks(mTriggerLongPress);
}
if (mDisallowIntercept != null) {
mSrc.removeCallbacks(mDisallowIntercept);
}
}
private void onLongPress() {
clearCallbacks();
final View src = mSrc;
if (!src.isEnabled()) {
return;
}
if (!onForwardingStarted()) {
return;
}
// Don't let the parent intercept our events.
mSrc.getParent().requestDisallowInterceptTouchEvent(true);
// Make sure we cancel any ongoing source event stream.
final long now = SystemClock.uptimeMillis();
final MotionEvent e = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0);
mSrc.onTouchEvent(e);
e.recycle();
mForwarding = true;
mWasLongPress = true;
}
/**
* Handled forwarded motion events and determines when to stop
* forwarding.
@@ -1379,6 +1442,13 @@ public class ListPopupWindow {
parent.requestDisallowInterceptTouchEvent(true);
}
}
private class TriggerLongPress implements Runnable {
@Override
public void run() {
onLongPress();
}
}
}
/**