Detectando una pulsación larga en Android
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_DOWN
y ver cuanto tiempo falta antesACTION_UP
.
¿Cómo se detectan pulsaciones prolongadas en Android usando opengl-es?
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);
}
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);
};
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.
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
}