android onclicklistener ontouchlistener

android - Cómo combinar OnClickListener y OnTouchListener para un ImageButton



(5)

Dado que ambas acciones consisten en los gestos "poner el dedo en la pantalla - levante el dedo de la pantalla", no puede determinar si fue una acción táctil o una acción de clic. Entonces, si implementa ambos oyentes en este botón de imagen, un toque / clic cambiará la imagen Y presionará el botón. No estoy seguro si hay un orden determinado de estos eventos ...

Sin embargo, si desea separar estos eventos, deberá definir un gesto diferente para una de las acciones (como limpiar para cambiar la imagen) o crear diferentes áreas para manejar los eventos, por ejemplo, la imagen no se ajusta El botón completo y el área libre sirven como área de clic de botón.

HTH

Actualizar:

Me di cuenta de que un TouchEvent es más general que un ClickEvent lo que se llama primero.

public abstract boolean onTouch (View v, MotionEvent event)

Esto devuelve verdadero, si el oyente ha consumido el evento, falso de lo contrario. Por lo tanto, puede decidir en su implementación si el evento también debe ser manejado por OnClickListener, luego simplemente devuelva false .

Necesito hacer algo cuando el usuario hace clic en el botón ImageButton . He intentado crear una clase estática que implementa tanto OnClickListener como OnTouchListener

static class ClickListenerForScrolling implements OnClickListener, OnTouchListener

que tiene los siguientes métodos:

@Override public void onClick(View v)

y

@Override public boolean onTouch(View arg0, MotionEvent arg1)

La idea detrás de esto es cambiar la fuente de imagen de ImageButton cuando el usuario la toca y realizar una tarea cuando el usuario hace clic en este botón. ¿Alguien puede darme una pista sobre cómo hacer esto?


El onTouchListener es capaz de manejar ambos movimientos.

Switch entre los valores de event.action() para obtener MotionEvent .

case MotionEvent.ACTION_DOWN : es el primer impacto del dedo.
case MotionEvent.ACTION_UP : es cuando el dedo desaparece.

Tendrás que establecer el punto de impacto en ACTION_DOWN .

TheImpactPoint=event.getX();

Y luego obtener la distancia con ACTION_UP

float distance =TheImpactPoint-event.getX();

If distance = 0 entonces hay un clic, de lo contrario sería más o menos que cero dependiendo del gesto.

Por lo tanto, esta es la forma de usar el evento de clic sin un evento de clic real y usando solo el onTouchListener .

La esperanza será útil.


Hay muchas soluciones para este problema, la mejor para mí es eliminar totalmente el setOnClickListener y dentro del onTouchListener comprobar si la acción es ACTION_UP y luego dentro de esa verificación si el último antes es ACTION_DOWN:

case MotionEvent.ACTION_UP: if (lastAction == MotionEvent.ACTION_DOWN) { //code for click . . lastAction = event.getAction(); }

lastAction es int y lo actualizo al final de cada ACCIÓN


Usa este código:

public class GestureHelper implements OnTouchListener { private final GestureDetector mGestureDetector; public GestureHelper(Context context) { mGestureDetector = new GestureDetector(context, new GestureListener(this)); } public void onSwipeRight() { }; public void onSwipeLeft() { }; public void onSwipeTop() { }; public void onSwipeBottom() { }; public void onDoubleTap() { }; public void onClick() { }; @Override public boolean onTouch(View v, MotionEvent event) { return mGestureDetector.onTouchEvent(event); } private static final class GestureListener extends SimpleOnGestureListener { private static final int SWIPE_THRESHOLD = 100; private static final int SWIPE_VELOCITY_THRESHOLD = 100; private GestureHelper mHelper; public GestureListener(GestureHelper helper) { mHelper = helper; } @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onSingleTapUp(MotionEvent e) { mHelper.onClick(); return true; } @Override public boolean onDoubleTap(MotionEvent e) { mHelper.onDoubleTap(); return true; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { boolean result = false; try { float diffY = e2.getY() - e1.getY(); float diffX = e2.getX() - e1.getX(); if (Math.abs(diffX) > Math.abs(diffY)) { if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { if (diffX > 0) { mHelper.onSwipeRight(); } else { mHelper.onSwipeLeft(); } } } else { if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { if (diffY > 0) { mHelper.onSwipeBottom(); } else { mHelper.onSwipeTop(); } } } } catch (Exception ex) { ex.printStackTrace(); } return result; } } }

Extiende esta clase y usa así ...

view.setOnTouchListener(new SomeYourGestureHelper(context, someParameters));


Utilice return false lugar de return true