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;
}
}
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With