How do I get my view to stop listening to touch events after ACTION_MOVE?
android, android-animation, ontouchlistener
Solution
Why you just don't keep listening but set an statement to ignore the motion event?
Something like that:
private static class AnimationOnTouchListener implements View.OnTouchListener {
private Rect rect;
private boolean ignore = false;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(ignore && motionEvent.getAction()!=MotionEvent.ACTION_UP)
return false;
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
rect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
animatePressed();
return false;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
// back to normal state
animateBackToNormal();
// IMPORTANT - touch down won't work if this isn't there.
ignore = false;
return false;
case MotionEvent.ACTION_MOVE:
if(!rect.contains(view.getLeft() + (int) motionEvent.getX(), view.getTop() + (int) motionEvent.getY())){
d(TAG, "out of bounds");
animateBackToNormal();
// STOP LISTENING TO MY TOUCH EVENTS!
ignore = true;
} else {
d(TAG, "in bounds");
}
return false;
default:
return true;
}
}
Problem
I have a button that I'm animating on button press. I want it to snap back to its "normal" state after I drag outside a certain threshold. I create a rectangle of the view bounds on `ACTION_DOWN` and check whether it's out of the touch area in `ACTION_MOVE`. I successfully detect the "out of bounds" touch, but I can't get the view to stop listening to touches. It's like it ignores my animateToNormal() method. I've tried changing the boolean return value to true instead of false, which didn't help. I've also tried removing the touch listener in the `ACTION_MOVE` case (set null), but I need to re-attach to continue listening to touches. I figure I can add an arbitrary delay before adding it back, but that seems like a terrible hack. I'm testing this on a 4.2 device (LG G2). ``` private static class AnimationOnTouchListener implements View.OnTouchListener { private Rect rect; @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch(motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: rect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); animatePressed(); return false; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: // back to normal state animateBackToNormal(); return false; case MotionEvent.ACTION_MOVE: if(!rect.contains(view.getLeft() + (int) motionEvent.getX(), view.getTop() + (int) motionEvent.getY())){ d(TAG, "out of bounds"); animateBackToNormal(); // STOP LISTENING TO MY TOUCH EVENTS! } else { d(TAG, "in bounds"); } return false; default: return true; } } ```