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; }