Detectando una pulsación larga en Android

Resuelto Jack asked hace 54 años • 11 respuestas

Actualmente estoy usandoonTouchEvent(MotionEvent event) { } para detectar cuando el usuario presiona mi glSurfaceView. ¿Existe alguna manera de detectar cuando se realiza un clic prolongado?

Supongo que si no puedo encontrar mucho en los documentos de desarrollo, entonces será algún tipo de método alternativo. Algo así como registrarse ACTION_DOWNy ver cuanto tiempo falta antesACTION_UP .

¿Cómo se detectan pulsaciones prolongadas en Android usando opengl-es?

Jack avatar Jan 01 '70 08:01 Jack
Aceptado

detector de gestos es la mejor solución.

Aquí tienes una alternativa interesante. En onTouchEvent, en cada ACTION_DOWN, programe un Runnable para que se ejecute en 1 segundo. En cada ACTION_UP o ACTION_MOVE , cancele el Runnable programado. Si la cancelación ocurre menos de 1 segundo después del evento ACTION_DOWN , Runnable no se ejecutará.

final Handler handler = new Handler(); 
Runnable mLongPressed = new Runnable() { 
    public void run() { 
        Log.i("", "Long press!");
    }   
};

@Override
public boolean onTouchEvent(MotionEvent event, MapView mapView){
    if(event.getAction() == MotionEvent.ACTION_DOWN)
        handler.postDelayed(mLongPressed, ViewConfiguration.getLongPressTimeout());
    if((event.getAction() == MotionEvent.ACTION_MOVE)||(event.getAction() == MotionEvent.ACTION_UP))
        handler.removeCallbacks(mLongPressed);
    return super.onTouchEvent(event, mapView);
}
MSquare avatar Jul 27 '2012 00:07 MSquare

Prueba esto:

final GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
    public void onLongPress(MotionEvent e) {
        Log.e("", "Longpress detected");
    }
});

public boolean onTouchEvent(MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
};
Daniel Fekete avatar Oct 27 '2011 19:10 Daniel Fekete

Tengo un código que detecta un clic, un clic largo y movimiento. Es bastante una combinación de la respuesta dada anteriormente y los cambios que hice al mirar cada página de documentación.

//Declare this flag globally
boolean goneFlag = false;

//Put this into the class
final Handler handler = new Handler(); 
    Runnable mLongPressed = new Runnable() { 
        public void run() { 
            goneFlag = true;
            //Code for long click
        }   
    };

//onTouch code
@Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {    
        case MotionEvent.ACTION_DOWN:
            handler.postDelayed(mLongPressed, 1000);
            //This is where my code for movement is initialized to get original location.
            break;
        case MotionEvent.ACTION_UP:
            handler.removeCallbacks(mLongPressed);
            if(Math.abs(event.getRawX() - initialTouchX) <= 2 && !goneFlag) {
                //Code for single click
                return false;
            }
            break;
        case MotionEvent.ACTION_MOVE:
            handler.removeCallbacks(mLongPressed);
            //Code for movement here. This may include using a window manager to update the view
            break;
        }
        return true;
    }

Confirmo que está funcionando ya que lo he usado en mi propia aplicación.

Sanved avatar Mar 22 '2015 08:03 Sanved

He creado un fragmento , inspirado en la fuente de visualización real, que detecta de manera confiable clics/presiones prolongadas con un retraso personalizado. Pero está en Kotlin:

val LONG_PRESS_DELAY = 500

val handler = Handler()
var boundaries: Rect? = null

var onTap = Runnable {
    handler.postDelayed(onLongPress, LONG_PRESS_DELAY - ViewConfiguration.getTapTimeout().toLong())
}

var onLongPress = Runnable {

    // Long Press
}

override fun onTouch(view: View, event: MotionEvent): Boolean {
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            boundaries = Rect(view.left, view.top, view.right, view.bottom)
            handler.postDelayed(onTap, ViewConfiguration.getTapTimeout().toLong())
        }
        MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
            handler.removeCallbacks(onLongPress)
            handler.removeCallbacks(onTap)
        }
        MotionEvent.ACTION_MOVE -> {
            if (!boundaries!!.contains(view.left + event.x.toInt(), view.top + event.y.toInt())) {
                handler.removeCallbacks(onLongPress)
                handler.removeCallbacks(onTap)
            }
        }
    }
    return true
}
Benjoyo avatar Feb 05 '2017 16:02 Benjoyo