2010-07-13 19 views
5

Estoy haciendo un juego en Android y tengo que hacer ciertas acciones cuando los usuarios intenten presionar la pantalla. Desafortunadamente no he encontrado ningún método que funcione directamente con un SurfaceView personalizado, siéntase libre de decirme si existe dicho método :)Long Touch en un surfaceView (android)

Así que decidí intentar implementar una detección táctil prolongada desde el detector de eventos onTouch.

aquí es mi código:

@Override 
    public boolean onTouch(View v, MotionEvent event) 
    { 
     long touchDuration = 0; 


      if (event.getAction() == MotionEvent.ACTION_DOWN) 
      { 
       //Start timer 
       touchTime = System.currentTimeMillis(); 


      }else if (event.getAction() == MotionEvent.ACTION_UP) 
      { 
       //stop timer 
       touchDuration = System.currentTimeMillis() - touchTime; 

       if (touchDuration < 800) 
       { 
        onShortTouch(event,touchDuration); 
       }else 
       { 
        onLongTouch(event,touchDuration); 
       } 
      } 
     } 

     return true; 

Esto funciona, pero puede detectar si la prensa era una pulsación larga o no sólo cuando el usuario deja de tocar el teléfono. Entonces no es exactamente lo que quiero. Preferiría que un temporizador se inicie cuando el usuario toque la pantalla por primera vez y, una vez transcurridos 800 ms, se invoque el método LongTouch(). En otras palabras, no quiero tener que verificar cuánto tiempo ha transcurrido cuando ACTION_UP desde ACTION_DOWN. Creo que debería usar un hilo para dicho temporizador pero no puedo hacerlo funcionar. Cuando se utiliza el siguiente código, el mensaje de depuración se muestra en cuanto toco la pantalla:

 @Override 
    public boolean onTouch(View v, MotionEvent event) 
    { 
     long touchDuration = 0; 

      TouchThread touchThread = new TouchThread(); 

      if (event.getAction() == MotionEvent.ACTION_DOWN) 
      { 
       //Start timer 
       touchTime = System.currentTimeMillis(); 
       touchThread.setEvent(event); 
       touchThread.run(); 
      } 

     return true; 
    } 


    private class TouchThread extends Thread 
    { 

      public MotionEvent event = null; 

      public void setEvent(MotionEvent e) 
      { 
       event = e; 
      } 

      @Override 
      public void run() 
      { 
       long startTime = System.currentTimeMillis(); 
       long time = 0; 

       while(event.getAction() == MotionEvent.ACTION_DOWN) 
       { 
        time = System.currentTimeMillis() - startTime; 
        if(time > 800) 
        { 
         System.out.println("LOOONG CLICK!!"); 
         return; 
        } 
       } 
      } 
    } 

Alguien tiene alguna idea? Otra solución también sería bienvenida.

Gracias.

Respuesta

3

Una buena opción cuando usted también quiere hacer algo de procesamiento de eventos es manual de la clase GestureDetector: http://developer.android.com/reference/android/view/GestureDetector.html

¿Cómo lo uso es para hacer una instancia GestureDetector en el constructor, implementar los métodos que me interesa, y luego en el inicio del método onTouchEvent() hacer algo como:

if (gestureDetector.onTouchEvent(event)) { 
     return true; 
    } 

¿Qué significa entonces en la mayoría de los casos cuando se detecta un gesto que se anula el resto de su manejo táctil. Sin embargo, la pulsación larga es un poco diferente porque el método de pulsación larga no devuelve un valor. En este caso, tengo un booleano en algún lugar que establezco cuando se activa una pulsación larga que luego verifico en el método de manejo de eventos táctiles si es necesario.

1

Una cosa que puede hacer es configurar el OnLongClickListener en su SurfaceView.

mySurfaceView.setOnLongClickListener(l); 

Luego, en su SurfaceView, es necesario anular el onTouchEvent:

public boolean onTouchEvent(MotionEvent event) { 
    super.onTouchEvent(event); 
    return true; 
} 
3

Es bastante fácil, en realidad. En el constructor de su punto de vista, hacer esto:

setOnLongClickListener(new View.OnLongClickListener() 
{ 
    public boolean onLongClick(View v) { 
     Log.v("debug", "LONG CLICK!"); 
     return true; 
    } 
    } 
); 

Entonces anulan onTouchEvent:

@Override 
    public boolean onTouchEvent(MotionEvent event) { 
     super.onTouchEvent(event); 
    } 

y listo;).

Cuestiones relacionadas