如何在Android中使用OnTouchListener捕获双击事件

我正在尝试使用OnTouchListener来捕获双击事件。 我想我会为motionEvent.ACTION_DOWN设置一个很长的时间,为第二个motionEvent.ACTION_DOWN设置一个不同的长度,然后测量两个人之间的时间,然后用它做一些事情。 但是,我很难搞清楚如何处理这个问题。 我正在使用开关盒来拾取多点触摸事件,所以我宁愿不尝试和重新制作这一切来实现GestureDetector(不幸的是,不可能同时实现ontouchlistener和Gesturedetector)。 任何想法都会大大帮助:

i.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { ImageView i = (ImageView) v; switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: long firstTouch = System.currentTimeMillis(); ///how to grab the second action_down???? break; 

Solutions Collecting From Web of "如何在Android中使用OnTouchListener捕获双击事件"

我较早解决了这个问题。 它涉及到使用处理程序等待一定的时间等待第二次点击: 如何按菜单button时,创build单击事件和双击事件?

在你的class级定义中:

 public class main_activity extends Activity { //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 int MAX_DURATION = 500; } 

然后在你的课堂上:

 OnTouchListener MyOnTouchListener = new OnTouchListener() { @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(duration<= MAX_DURATION) { Toast.makeText(captureActivity.this, "double tap",Toast.LENGTH_LONG).show(); } clickCount = 0; duration = 0; break; } } return true; } } 

这是从一个答案改编: Android中的DoubleTap通过https://stackoverflow.com/users/1395802/karn

使用实现GestureListener和OnDoubleTapListener的帮助程序类SimpleGestureListener,您不需要太多操作。

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

这很容易:

 //variable for storing the time of first click long startTime; //constant for defining the time duration between the click that can be considered as double-tap static final int MAX_DURATION = 200; if (event.getAction() == MotionEvent.ACTION_UP) { startTime = System.currentTimeMillis(); } else if (event.getAction() == MotionEvent.ACTION_DOWN) { if(System.currentTimeMillis() - startTime <= MAX_DURATION) { //DOUBLE TAP } } 

如果你想实现双击,你应该看看GestureDetector的源代码。 这非常简单明了。

这是我的解决scheme。

快速清晰的“单击”和“双击”是非常重要的。 我首先尝试了GestureDetector但结果非常糟糕。 也许我的嵌套使用scrollviews的结果 – 谁知道…

我专注于MotionEvent.ACTION_UP和tapped元素的ID。 为了保持第一次点击活着,我使用Handler发送一个延迟的消息(350毫秒),这样用户有一段时间在ImageView上进行第二次点击。 如果用户第二次敲击具有相同ID的元素,我将其作为双击,删除延迟的消息,并破坏我的自定义代码“双击”。 如果用户在具有不同ID的元素上点击,则将其作为新的点击并为其创build另一个Handler程序。

类全局variables

 private int tappedItemId = -1; Handler myTapHandler; final Context ctx = this; 

代码示例

 ImageView iv = new ImageView(getApplicationContext()); //[...] iv.setId(i*1000+n); iv.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_UP: { //active 'tap handler' for current id? if(myTapHandler != null && myTapHandler.hasMessages(v.getId())) { // clean up (to avoid single tap msg to be send and handled) myTapHandler.removeMessages(tappedItemId); tappedItemId = -1; //run 'double tap' custom code Toast.makeText(ScrollView.this, "double tap on "+v.getId(), Toast.LENGTH_SHORT).show(); return true; } else { tappedItemId = v.getId(); myTapHandler = new Handler(){ public void handleMessage(Message msg){ Toast.makeText(ctx, "single tap on "+ tappedItemId + " msg 'what': " + msg.what, Toast.LENGTH_SHORT).show(); } }; Message msg = Message.obtain(); msg.what = tappedItemId; msg.obj = new Runnable() { public void run() { //clean up tappedItemId = -1; } }; myTouchHandler.sendMessageDelayed(msg, 350); //350ms delay (= time to tap twice on the same element) } break; } } return true; } });