Tacto largo en una superficieView (android)
Estoy haciendo un juego en Android y necesito hacer ciertas acciones cuando los usuarios intentan pulsar larga en la pantalla. Lamentablemente no he encontrado ningún método que funcione directamente con un SurfaceView personalizado, siéntase libre de decirme si tal método existe 🙂
Así que decidí probar e implementar una detección de tacto largo desde el detector de eventos onTouch.
- Iniciar un servicio en un proceso separado android
- Cómo pasar un argumento a un hilo
- Ejecutar una tarea larga en glThread sin bloquear el hilo de la interfaz de usuario en Android
- Cómo detener el lanzamiento de un hilo hecho con postDelayed
- Android hilo problema, ¿por qué ui todavía bloquea cuando he utilizado un hilo de trabajo?
Aquí está 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 puedo detectar si la prensa era una prensa larga o no sólo cuando el usuario deja de tocar el teléfono. Así que no es exactamente lo que quiero. Preferiría que un temporizador se inicie cuando el usuario toque la pantalla por primera vez, una vez transcurrido 800 ms se llama al método LongTouch (). En otras palabras, no quiero tener que comprobar cuánto tiempo ha transcurrido cuando ACTION_UP desde ACTION_DOWN. Creo que debería usar un hilo para dicho temporizador pero no puedo hacer que funcione. Cuando se utiliza el código siguiente, el mensaje de depuración se muestra tan pronto como 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 sería también bienvenida.
Gracias.
- Comportamiento del contexto de Android AsyncTask
- ¿Cuál es el propósito de sSyncAdapterLock en la muestra SyncService?
- Registrar un receptor de difusión de un servicio en un nuevo hilo
- SQLite lectura y escritura simultánea
- AsyncTask con rotación de pantalla - onRetainNonConfigurationInstance obsoleta
- Android cómo ejecutarOnUiThread en otra clase?
- Escritura y lectura entre subprocesos con Android Realm
- ¿Por qué mis hilos no mueren y causan una pérdida de memoria?
Una buena opción cuando también desea realizar algún procesamiento manual de eventos es la clase GestureDetector: http://developer.android.com/reference/android/view/GestureDetector.html
Cómo lo uso es hacer una instancia de GestureDetector en el constructor, poner en práctica los métodos que me interesan y, a continuación, al comienzo del método onTouchEvent () hacer algo como:
if (gestureDetector.onTouchEvent(event)) { return true; }
Lo que significa que en la mayoría de los casos, cuando se detecta un gesto que aborta el resto de su manejo táctil. Sin embargo, la prensa larga es un poco diferente porque el método de la prensa larga no devuelve un valor. En este caso, sólo tengo un booleano en algún lugar que establezco cuando se activa una pulsación larga que compruebo más tarde en el método de manejo de eventos táctiles si es necesario.
Es muy fácil, en realidad. En el constructor de su vista, haga lo siguiente:
setOnLongClickListener(new View.OnLongClickListener() { public boolean onLongClick(View v) { Log.v( "debug", "LONG CLICK!" ); return true; } } );
A continuación, anule onTouchEvent:
@Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); }
Y usted es fijado;).
Una cosa que puedes hacer es establecer OnLongClickListener en tu SurfaceView.
mySurfaceView.setOnLongClickListener(l);
A continuación, en su SurfaceView, debe anular el onTouchEvent:
public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); return true; }
- Estilo Android – diferencia entre @style, android :, @android: style, etc
- Android: varios appWidgets que reproducen diferentes sonidos