Android MotionEvent: find out if there was a movement outside the view

I have a button and OnTouchListener attached to it. How can I find if there was a movement (when the user clicks the button) inside or outside? Both event.getAction () and event.getActionMasked () return only 0, 1, or 2, which are ActionDown, ActionUp, ActionMove, respectively. There's a constant MotionEvent.ACTION_OUTSIDE, which is 4, but somehow I don’t get it, even if I drag the contact outside the button, I still get 2 from both methods. What is the problem?

UPD: I found a nice solution - just check the focused state in sight after ACTION_UP. If it is not focused, it means that the movement has occurred outside of the view.

+7
source share
5 answers

This flag applies only to Windows, not to views. You will receive ACTION_MOVE when you move your finger away from the view, the event remains in the view. Check out the source code for SeekBar if you need clarification: even if you release your finger from the panel, the thumb still drags!

To do this, use FLAG_WATCH_OUTSIDE_TOUCH at the window level, it works fine.

+7
source

case MotionEvent.ACTION_CANCEL worked for me.

+5
source

The MotionEvent.ACTION_OUTSIDE function does not work for the View.

One solution is to get the touch position of X and Y and check if it is within sight. This can be done as follows:

 @Override public boolean onTouchEvent(MotionEvent e) { if (e.getX()<0 || e.getY()<0 || e.getX()>getMeasuredWidth() || e.getY()>getMeasuredHeight()) Log.i(TAG, "TOUCH OUTSIDE"); else Log.i(TAG, "TOUCH INSIDE"); return true; } 
+4
source

If the OnTouchListener is on Button , you will only get motion events from Button . MotionEvent.ACTION_OUTSIDE will only be called when the motion event first goes beyond the View , and you should treat it as if it were ACTION_UP .

+3
source
 public static boolean touchWithinBounds(MotionEvent event, View view) { if (event == null || view == null || view.getWidth() == 0 || view.getHeight() == 0) return false; int[] viewLocation = new int[2]; view.getLocationOnScreen(viewLocation); int viewMaxX = viewLocation[0] + view.getWidth() - 1; int viewMaxY = viewLocation[1] + view.getHeight() - 1; return (event.getRawX() <= viewMaxX && event.getRawX() >= viewLocation[0] && event.getRawY() <= viewMaxY && event.getRawY() >= viewLocation[1]); } 

Solution when forwarding a touch event from another view

0
source

All Articles