Singletap touch detect en método Ontouch de la vista

Necesitaba una detección de toque singletap en el método ontouch de mi vista personalizada. Traté de obtener los valores xyy en ACTION-DOWN y ACTION-UP y en ACTION-UP dí una condición de que si a los valores de X e Y en ACTIONDOWN y ACTION-UP son iguales, entonces tomarlo como un solo toque .

Mi código es el siguiente

@Override public boolean onTouchEvent(MotionEvent ev) { if (!mSupportsZoom && !mSupportsPan) return false; mScaleDetector.onTouchEvent(ev); final int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { final float x = ev.getX(); final float y = ev.getY(); mLastTouchX = x; //here i get x and y values in action down mLastTouchY = y; mActivePointerId = ev.getPointerId(0); break; } case MotionEvent.ACTION_MOVE: { final int pointerIndex = ev.findPointerIndex(mActivePointerId); final float x = ev.getX(pointerIndex); final float y = ev.getY(pointerIndex); if (mSupportsPan && !mScaleDetector.isInProgress()) { final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; mPosX += dx; mPosY += dy; //mFocusX = mPosX; //mFocusY = mPosY; invalidate(); } mLastTouchX = x; mLastTouchY = y; break; } case MotionEvent.ACTION_UP: { final float x = ev.getX(); final float y = ev.getY(); touchupX=x; //here is get x and y values at action up touchupY=y; if(mLastTouchX == touchupX && mLastTouchY == touchupY){ //my condition if both the x and y values are same . PinchZoomPanActivity2.tapped1(this.getContext(), 100); //my method if the singletap is detected } else{ } mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_CANCEL: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_POINTER_UP: { final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = ev.getPointerId(pointerIndex); if (pointerId == mActivePointerId) { final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastTouchX = ev.getX(newPointerIndex); mLastTouchY = ev.getY(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); } break; } } return true; } 

Pero no puedo hacerlo. Quiero decir que en cada acción de mi método se llama. Incluso cuando los valores xey de actionup y actiondown no son los mismos. Y creo que también tengo que poner un poco de rango para el singletap como tocamos con nuestro dedo en la pantalla. ¿Puede alguien sugerirme algunas maneras?

También me encontré con el mismo problema recientemente y terminé teniendo que implementar un debounce para que funcione. No es ideal, pero es bastante confiable hasta que pueda encontrar algo mejor.

View.onClickListener era mucho más confiable para mí, pero desafortunadamente necesito el MotionEvent del OnTouchListener.

Editar: eliminado el código en exceso que causaría que fallara aquí

 class CustomView extends View { private static long mDeBounce = 0; static OnTouchListener listenerMotionEvent = new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if ( Math.abs(mDeBounce - motionEvent.getEventTime()) < 250) { //Ignore if it's been less then 250ms since //the item was last clicked return true; } int intCurrentY = Math.round(motionEvent.getY()); int intCurrentX = Math.round(motionEvent.getX()); int intStartY = motionEvent.getHistorySize() > 0 ? Math.round(motionEvent.getHistoricalY(0)) : intCurrentY; int intStartX = motionEvent.getHistorySize() > 0 ? Math.round(motionEvent.getHistoricalX(0)) : intCurrentX; if ( (motionEvent.getAction() == MotionEvent.ACTION_UP) && (Math.abs(intCurrentX - intStartX) < 3) && (Math.abs(intCurrentY - intStartY) < 3) ) { if ( mDeBounce > motionEvent.getDownTime() ) { //Still got occasional duplicates without this return true; } //Handle the click mDeBounce = motionEvent.getEventTime(); return true; } return false; } }; } 

Para detectar Single y Double Tap en android Estoy usando los siguientes métodos:

 class GestureTap extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDoubleTap(MotionEvent e) { Log.i("onDoubleTap :", "" + e.getAction()); return true; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { Log.i("onSingleTap :", "" + e.getAction()); return true; } } 

Utilícelo en el constructor de GestureDetector:

 detector = new GestureDetector(this, new GestureTap()); 

Y agrega el siguiente código en el listener de onTouch

 @Override public boolean onTouchEvent(MotionEvent event) { detector.onTouchEvent(event); return true; } 

Agregando la respuesta para el bien de la completitud y si alguien más llega aquí:

Puede utilizar un GestureDetector con un OnTouchListener

 final GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapConfirmed(MotionEvent e) { //do something return true; } @Override public void onLongPress(MotionEvent e) { super.onLongPress(e); } @Override public boolean onDoubleTap(MotionEvent e) { return super.onDoubleTap(e); } }); viewToTouch.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return gestureDetector.onTouchEvent(event); } }); 

Agregue GestureDetector.SimpleOnGestureListener para ver y usar el método onSingleTapConfirmed en este.

Este método se invoca sólo cuando Android OS ha confirmado el toque en el particular es solo toque y no toque dos veces .

Puedes google para ejemplos de android.

Hay una forma mucho más sencilla y directa. Utilice MotionEvent.ACTION_DOWN && MotionEvent.ACTION_UP y sincronice la diferencia entre los eventos.

El código completo se puede encontrar aquí. https://stackoverflow.com/a/15799372/3659481

 setOnTouchListener(new OnTouchListener() { private static final int MAX_CLICK_DURATION = 200; private long startClickTime; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { startClickTime = Calendar.getInstance().getTimeInMillis(); break; } case MotionEvent.ACTION_UP: { long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime; if(clickDuration < MAX_CLICK_DURATION) { //click event has occurred } } } return true; } 

}

Piensa que no necesitas usar un operador "igual". En lugar de utilizar un valor aproximado

 case MotionEvent.ACTION_DOWN: { final int CONST = 5; final float x = ev.getX(); final float y = ev.getY(); mLastTouchXMax = x+CONST; //here i get x and y values in action down mLastTouchXMin = x-CONST; mLastTouchYMax = y+CONST; mLastTouchYMin = y-CONST; mActivePointerId = ev.getPointerId(0); break; } 

Y en ACTION_UP verifique los valores de X e Y entre intervalos.

 float dX,dY,x,y; tv.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_UP: //Event for On Click if(x==view.getX() && y==view.getY()){ Toast.makeText(getApplicationContext(),"TextView Clicked",Toast.LENGTH_LONG).show(); } break; case MotionEvent.ACTION_DOWN: x=view.getX(); y=view.getY(); dX = view.getX() - event.getRawX(); dY = view.getY() - event.getRawY(); break; case MotionEvent.ACTION_MOVE: view.animate() .x(event.getRawX() + dX) .y(event.getRawY() + dY) .setDuration(0) .start(); break; default: return false; } return true; } }); 
  • Android ListView áreas parciales presionables
  • Navegador Android: touchcancel está siendo disparado aunque touchmove tiene preventDefault
  • Manejo de eventos táctiles - onInterceptTouchEvent y onTouchEvent
  • Cómo hacer la detección de objetos en opengl Android?
  • Arrastre con velocidad en el juego Unity no igual dependiendo de la resolución
  • Creación de ImageButton de forma irregular con diferentes estados de clic
  • WebView en Galería deteniendo eventos de desplazamiento / toque
  • Android detecta el estado táctil desde cualquier aplicación
  • Android: delegar evento táctil a la vista inferior
  • Manejo de MotionEvent en ScrollView en Android
  • ¿Por qué no funciona esta simulación de MotionEvent?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.