Send cancel event to recycled views instead of an up.

Bug #2309387

This was a problem in lists with list items that would cause notifyDatasetChanged()
interleaved with a series of up/down motion events. This is a pretty rare case
but it's worth fixing it to avoid getting views in a weird state.
This commit is contained in:
Romain Guy
2010-02-26 11:56:30 -08:00
parent b5e15690dc
commit 8afa515936
2 changed files with 21 additions and 0 deletions

View File

@@ -1506,6 +1506,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
*/
private static final int PREPRESSED = 0x02000000;
/**
* Indicates whether the view is temporarily detached.
*
* @hide
*/
static final int CANCEL_NEXT_UP_EVENT = 0x04000000;
/**
* Always allow a user to overscroll this view, provided it is a
* view that can scroll.
@@ -3668,6 +3675,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
*/
public void onStartTemporaryDetach() {
removeUnsetPressCallback();
mPrivateFlags |= CANCEL_NEXT_UP_EVENT;
}
/**
@@ -5913,6 +5921,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* @see #onAttachedToWindow()
*/
protected void onDetachedFromWindow() {
mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
removeUnsetPressCallback();
removeLongPressCallback();
destroyDrawingCache();

View File

@@ -859,6 +859,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final float xc = scrolledXFloat - child.mLeft;
final float yc = scrolledYFloat - child.mTop;
ev.setLocation(xc, yc);
child.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
if (child.dispatchTouchEvent(ev)) {
// Event handled, we have a target now.
mMotionTarget = child;
@@ -889,6 +890,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// We don't have a target, this means we're handling the
// event as a regular view.
ev.setLocation(xf, yf);
if ((mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) {
ev.setAction(MotionEvent.ACTION_CANCEL);
mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
}
return super.dispatchTouchEvent(ev);
}
@@ -897,6 +902,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (!disallowIntercept && onInterceptTouchEvent(ev)) {
final float xc = scrolledXFloat - (float) target.mLeft;
final float yc = scrolledYFloat - (float) target.mTop;
mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
ev.setAction(MotionEvent.ACTION_CANCEL);
ev.setLocation(xc, yc);
if (!target.dispatchTouchEvent(ev)) {
@@ -921,6 +927,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final float yc = scrolledYFloat - (float) target.mTop;
ev.setLocation(xc, yc);
if ((target.mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) {
ev.setAction(MotionEvent.ACTION_CANCEL);
target.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
mMotionTarget = null;
}
return target.dispatchTouchEvent(ev);
}