2012-06-23 10 views
7

Tengo un botón y OnTouchListener conectado. ¿Cómo puedo saber si el movimiento (cuando el usuario presiona el botón) ocurre dentro o fuera de él? Tanto event.getAction() como event.getActionMasked() devuelven solo 0, 1 o 2, que son ActionDown, ActionUp, ActionMove, respectivamente. Hay un MotionEvent.ACTION_OUTSIDE constante, que es 4, pero de alguna manera no lo recibo, incluso si lo arrastro fuera del botón, aún recibo 2 de ambos métodos. ¿Cuál es el problema?Android MotionEvent: descubra si ocurrió movimiento fuera de la vista

UPD: He encontrado una buena solución - simplemente 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.

Respuesta

7

Ese indicador solo se aplica a Windows, no a Vistas. Obtendrá ACTION_MOVE cuando mueva su dedo fuera de la Vista, el evento permanecerá en Ver con el que se originó. Mira el código fuente para SeekBar si necesitas una aclaración: incluso si mueves el dedo fuera de la barra, ¡el pulgar aún se arrastra!

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

3

Si el OnTouchListener está en el Button, sólo recibirá los eventos de movimiento dentro de la Button. El MotionEvent.ACTION_OUTSIDE solo se ejecutará cuando el evento de movimiento salga por primera vez fuera de los límites del View, y debe tratarlo como si fuera un ACTION_UP.

5

case MotionEvent.ACTION_CANCEL funcionó para mí.

+0

Por qué esto no está marcado como respuesta, nunca sabrá. Gracias. :) –

+0

Esta respuesta realmente resuelve mi problema. Muchas gracias. –

4

MotionEvent.ACTION_OUTSIDE no funciona para View.

Una solución es obtener la posición táctil 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; 
} 
0
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]); 
} 

Solución para cuando estás reenviando un evento de toque de un punto de vista diferente

Cuestiones relacionadas