Android MotionEvent: averigua si el movimiento ocurrió fuera de la vista

Tengo un botón y OnTouchListener adjunto a él. ¿Cómo puedo encontrar si el movimiento (cuando el usuario pulsa el botón) sucedió dentro o fuera de él? Tanto event.getAction () como event.getActionMasked () devuelven sólo 0, 1 o 2, que es ActionDown, ActionUp, ActionMove, respectivamente. Hay un MotionEvent.ACTION_OUTSIDE constante, que es 4, pero de alguna manera no lo recibo aunque arrastre el toque fuera del botón – todavía recibo 2 de ambos métodos. ¿Cuál es el problema?

UPD: He encontrado una buena solución – solo verifique el estado enfocado en la vista después de ACTION_UP. Si no está enfocado, significa que el movimiento ocurrió fuera de la vista.

Ese indicador sólo se aplica a Windows, no a las vistas. Obtendrá ACTION_MOVE cuando mueva el dedo de la vista, el evento permanece en la vista con la que se originó. Mira el código fuente de SeekBar si necesitas aclaración: incluso si mueve el dedo de la barra, el pulgar sigue arrastrando!

Para hacer esto en el nivel de ventana use FLAG_WATCH_OUTSIDE_TOUCH , funciona muy bien.

Si el OnTouchListener está en el Button , sólo recibirá eventos de movimiento desde el Button . El objeto MotionEvent.ACTION_OUTSIDE sólo se llamará cuando el evento de movimiento primero salga de los límites de la View y debería tratarse como si fuera un ACTION_UP .

case MotionEvent.ACTION_CANCEL funcionó para mí.

El objeto MotionEvent.ACTION_OUTSIDE no funciona para View.

Una solución es obtener la posición de toque X e Y y verificar si está dentro de los límites de la vista. Se puede hacer así:

 @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; } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.