Android中的DoubleTap

我需要创建一个小文本区域。当我双击时,在该文本区域,它将移动到下一个活动。我怎么能这样做?

  • Android Studio需要在每次运行之前重建项目
  • 为什么Android会在Orientation Change上重新创建活动
  • Android:从最佳可用提供商处获取当前位置
  • 如何在低于Api的情况下设置View alpha?
  • Android执行时无效的命令行参数
  • 卡住了@SuppressLint(“NewApi”)(developer.android.com/training/basics/firstapp/starting-activity)
  • 如何降级到旧版Gradle
  • 在Java中划分两个整数给我0或100?
  • 如果你正确设置, GestureListenerOnDoubleTapListener非常有用。 您不需要处理每个单击并计算两者之间的时间。 相反,让Android为您处理点击,双击,滚动或投掷可能是什么。 使用实现GestureListenerOnDoubleTapListener的帮助器类SimpleGestureListener ,您不需要做太多事情。

     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; } }); 

    注意:我测试了很长一段时间才发现, return truereturn false的正确混合是什么。 这是非常棘手的部分。

    另一个注意事项:测试时,请在真实设备上进行 ,而不是模拟器。 我很难让鼠标快速创建onFling事件。 真实设备上的真实手指似乎要快得多。

    更好的选择是创建一个轻量级的Abstract Class

     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); } 

    并使用它

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

    在代码下使用非常简单的逻辑

      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; } 

    ———-

    我采用了一种不同的方法来实现对Android视图的双击。 我创建了自己的逻辑来检测双击,它很容易实现。

    以下是执行此操作的步骤:
    1.在要接收触摸事件的视图上设置onTouchListener。
    2.实现onTouch(视图,事件)方法。 (在双击时,键是检测两个ACTION_DOWN和ACTION_UP事件。为此我们将必须计算两个连续的下行事件之间的持续时间)。

    以下是实现此目的的逻辑:

      /* 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; } 

    ====编辑======

    对我来说,上面的描述是不可接受的,因为上面的逻辑不会超时。

    改用它

    @Override public boolean onTouch(View paramView,MotionEvent event){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(); } } 

    我有类似的问题,解决方案工作,直到我想做其他触摸事件,如刷卡和onLongPress。 从未调用过这些方法,所以我必须实现一个OnDoubleTapListener。 我做了如下:

     public class MainActivity extends Activity implements OnDoubleTapListener 

    然后只需实现三种方法

     @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; } 

    只需实现onDoubleTapEvent方法。 我不知道何时调用其他两个方法,但这对我有用

     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); }