DoubleTap en android

Necesito crear un área de texto pequeña. En ese área de texto cuando hago doble clic, se moverá a la siguiente actividad. ¿Cómo podría yo hacer esto?

Si usted hace la derecha de la disposición, el OnDoubleTapListener , dentro del GestureListener es muy útil. Usted no necesita manejar cada solo golpecito y cuenta el tiempo entre. En su lugar, deje que Android maneje para usted lo que un toque, un doble toque, un desplazamiento o fling podría ser. Con la clase de ayuda SimpleGestureListener que implementa el GestureListener y OnDoubleTapListener no necesita mucho que hacer.

 findViewById(R.id.touchableText).setOnTouchListener(new OnTouchListener() { private GestureDetector gestureDetector = new GestureDetector(Test.this, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDoubleTap(MotionEvent e) { Log.d("TEST", "onDoubleTap"); return super.onDoubleTap(e); } ... // implement here other callback methods like onFling, onScroll as necessary }); @Override public boolean onTouch(View v, MotionEvent event) { Log.d("TEST", "Raw event: " + event.getAction() + ", (" + event.getRawX() + ", " + event.getRawY() + ")"); gestureDetector.onTouchEvent(event); return true; } }); 

Nota: probé alrededor de bastante tiempo para averiguar, lo que la mezcla correcta de return true y return false es. Esta fue la parte realmente complicada aquí.

Otra nota: Cuando pruebes esto, hazlo en un dispositivo real , en lugar del emulador. Tuve problemas reales para obtener el ratón lo suficientemente rápido para crear un evento onFling. Los dedos reales en dispositivos reales parecen ser mucho más rápidos.

uso de la lógica muy simple debajo del código

  boolean firstTouch = false; @Override public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == event.ACTION_DOWN){ if(firstTouch && (Helper.getCurrentTimeInMilliSeconds() - time) <= 300) { //do stuff here for double tap Log.e("** DOUBLE TAP**"," second tap "); firstTouch = false; } else { firstTouch = true; time = Helper.getCurrentTimeInMilliSeconds(); Log.e("** SINGLE TAP**"," First Tap time "+time); return false; } } return true; } 

Una mejor alternativa es crear una clase abstracta ligera

 public abstract class DoubleClickListener implements OnClickListener { private static final long DOUBLE_CLICK_TIME_DELTA = 300;//milliseconds long lastClickTime = 0; @Override public void onClick(View v) { long clickTime = System.currentTimeMillis(); if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA){ onDoubleClick(v); lastClickTime = 0; } else { onSingleClick(v); } lastClickTime = clickTime; } public abstract void onSingleClick(View v); public abstract void onDoubleClick(View v); } 

Y utilizarlo como

  view.setOnClickListener(new DoubleClickListener() { @Override public void onSingleClick(View v) { } @Override public void onDoubleClick(View v) { } }); 

———-

Tomé un enfoque diferente para la aplicación de doble toque en las vistas de Android. He creado mi propia lógica para la detección de doble toque y es muy fácil de implementar.

Estos son los pasos para hacer esto:
1. Configure onTouchListener en la vista que desea recibir el evento táctil.
2. Implemente el método onTouch (view, event). (En la pulsación doble, la clave es detectar dos eventos ACTION_DOWN y ACTION_UP, para lo cual tendremos que calcular la duración del tiempo entre dos eventos descendentes sucesivos).

Aquí está la lógica para lograr esto:

  /* variable for counting two successive up-down events */ int clickCount = 0; /*variable for storing the time of first click*/ long startTime; /* variable for calculating the total time*/ long duration; /* constant for defining the time duration between the click that can be considered as double-tap */ static final MAX_DURATION = 500; @Override public boolean onTouch (View v, MotionEvent event) { switch(event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: startTime = System.currentTimeMillis(); clickCount++; break; case MotionEvent.ACTION_UP: long time = System.currentTimeMillis() - startTime; duration= duration + time; if(clickCount == 2) { if(totalTime <= DURATION) { Toast.makeText(captureActivity.this, "double tap",Toast.LENGTH_LONG).show(); } clickCount = 0; duration = 0; break; } } return true; } 

==== EDIT ======

Para mí lo anterior no es aceptable con los cambios sugeridos en el cooment – el tiempo de espera no funciona para la lógica anterior.

usa esto en su lugar

@Override public boolean onTouch (Ver paramView, evento MotionEvent) {switch (event.getAction () & MotionEvent.ACTION_MASK) {

  case MotionEvent.ACTION_UP: clickCount++; if (clickCount==1){ startTime = System.currentTimeMillis(); } else if(clickCount == 2) { long duration = System.currentTimeMillis() - startTime; if(duration <= ONE_SECOND) { Toast.makeText(captureActivity.this, "double tap",Toast.LENGTH_LONG).show(); clickCount = 0; duration = 0; }else{ clickCount = 1; startTime = System.currentTimeMillis(); } break; } } return true; 

}

 import android.app.Activity; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.GestureDetector.SimpleOnGestureListener; import android.widget.Toast; public class SimpleGestureFilter extends SimpleOnGestureListener { public final static int SWIPE_UP = 1; public final static int SWIPE_DOWN = 2; public final static int SWIPE_LEFT = 3; public final static int SWIPE_RIGHT = 4; public final static int MODE_TRANSPARENT = 0; public final static int MODE_SOLID = 1; public final static int MODE_DYNAMIC = 2; private final static int ACTION_FAKE = -13; private int swipe_Min_Distance = 100; private int swipe_Max_Distance = 350; private int swipe_Min_Velocity = 100; private int mode = MODE_DYNAMIC; private boolean running = true; private boolean tapIndicator = false; private Activity context; private GestureDetector detector; private SimpleGestureListener listener; public SimpleGestureFilter(Activity context,SimpleGestureListener sgf) { this.context = context; this.detector = new GestureDetector(context, this); this.listener = sgf; } public void onTouchEvent(MotionEvent me) { // TODO Auto-generated method stub if(!this.running) return; boolean result=this.detector.onTouchEvent(me); if(this.mode==MODE_SOLID) me.setAction(MotionEvent.ACTION_CANCEL); else if(this.mode==MODE_DYNAMIC) { if(me.getAction()==ACTION_FAKE) me.setAction(MotionEvent.ACTION_UP); else if(result) me.setAction(MotionEvent.ACTION_CANCEL); else if(this.tapIndicator) { me.setAction(MotionEvent.ACTION_DOWN); this.tapIndicator=false; } } } public void setMode(int m) { this.mode=m; } public int getMode() { return this.mode; } public void setEnabled(boolean status) { this.running=status; } public void setSwipeMaxDistance(int distance) { this.swipe_Max_Distance=distance; } public void setSwipeMinDistance(int distance) { this.swipe_Min_Distance=distance; } public int getSwipeMaxDistance() { return this.swipe_Max_Distance; } public int getSwipeMinDistance() { return this.swipe_Min_Distance; } public int getSwipeMinVelocity() { return this.swipe_Min_Velocity; } public boolean onFling(MotionEvent e1,MotionEvent e2,float velocityX,float velocityY) { final float xDistance=Math.abs(e1.getX()-e2.getX()); final float yDistance=Math.abs(e1.getY()-e2.getY()); if(xDistance>this.swipe_Max_Distance || yDistance> this.swipe_Max_Distance) return false; velocityX = Math.abs(velocityX); velocityY = Math.abs(velocityY); boolean result=false; if(velocityX > this.swipe_Min_Velocity && xDistance > this.swipe_Min_Distance) { if(e1.getX() > e2.getX()) // right to left Move this.listener.onSwipe(SWIPE_LEFT); else this.listener.onSwipe(SWIPE_RIGHT); result=true; } else if(velocityY > this.swipe_Min_Velocity && yDistance > this.swipe_Min_Distance) { if(e1.getY() > e2.getY()) // bottom to top Move this.listener.onSwipe(SWIPE_UP); else this.listener.onSwipe(SWIPE_DOWN); result=true; } return result; } public boolean onSingleTapUp(MotionEvent e) { this.tapIndicator=true; return false; } public boolean onDoubleTap(MotionEvent e) { this.listener.onDoubleTap(); return false; } public boolean onDoubleTapEvent(MotionEvent e) { return true; } public boolean onSingleTapConfirmed(MotionEvent e) { if(this.mode==MODE_DYNAMIC) { e.setAction(ACTION_FAKE); this.context.dispatchTouchEvent(e); } return false; } static interface SimpleGestureListener { void onSwipe(int direction); void onDoubleTap(); } } 

Tenía un problema similar y las soluciones de trabajo hasta que quería hacer otros eventos táctiles como swiping y onLongPress. Estos métodos nunca se invocaron así que tuve que implementar un OnDoubleTapListener. Hice lo siguiente:

 public class MainActivity extends Activity implements OnDoubleTapListener 

Entonces sólo implementar tres métodos

 @Override public boolean onDoubleTapEvent(MotionEvent e) { if(e.getAction()==1) { Toast.makeText(getApplicationContext(), "DOUBLE TAP",Toast.LENGTH_SHORT).show(); // TODO Auto-generated method stub // Implement code here!!! } return true; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { return true; } @Override public boolean onDoubleTap(MotionEvent e) { return true; } 

Simplemente implemente el método onDoubleTapEvent. No sé cuándo se invocan los otros dos métodos, pero esto funciona para mí

 X_View.setOnClickListener(new View.OnClickListener() { @Override public void onItemClick(View view) { long timeNow=Calendar.getInstance().getTimeInMillis(); long timeLastTapped=Long.valueOf(view.getTag().toString()); // Initially set to zero in adapter final int minDurationBetweenDoubleTap=500; if(timeLastTapped != 0) if( timeNow- timeLastTapped < minDurationBetweenDoubleTap) { Toast.makeText(getApplicationContext(), "DoubleTapped", 10).show(); } view.setTag(""+timeNow); } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.