我正在尝试使用OnTouchListener捕获双击事件。我想我会为motionEvent.ACTION_DOWN设置一个long,为第二个motionEvent.ACTION_DOWN设置一个不同的long,并测量它们之间的时间,然后用它做一些事情。但是,我很难弄清楚如何处理这个问题。我正在使用switch case来获取多点触控事件,所以我宁愿不尝试重新设计这一切以实现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;
答案 0 :(得分:12)
在班级定义中:
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;
}
}
中的答案改编的:https://stackoverflow.com/users/1395802/karn
答案 1 :(得分:8)
使用实现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;
}});
答案 2 :(得分:6)
N#39;这么容易:
//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
}
}
答案 3 :(得分:2)
我之前提到了这个问题。它涉及使用Handler等待一段时间等待第二次点击:How can I create a Single Click Event and Double Click Event when the Menu Button is pressed?
答案 4 :(得分:0)
这是我的解决方案。
对我来说,快速清晰地分离“单击”是非常重要的。和&#39;双击&#39;。
我先尝试GestureDetector
,但效果非常糟糕。也许是我嵌套使用scrollviews的结果 - 谁知道......
我专注于MotionEvent.ACTION_UP
和点击元素的ID。为了保持第一次点击活动,我使用Handler
发送延迟消息(350毫秒),以便用户有时间在ImageView
上进行第二次点击。如果用户再次点击具有相同ID的元素,我将其作为双击,删除延迟的消息并使用自定义代码来“双击”#39;。如果用户点击了具有不同ID的元素,我将其作为新点按,并为其创建另一个Handler
。
班级全局变量
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;
}
});
答案 5 :(得分:0)
使用Kotlin Coroutine支持单击和双击的另一种方法:
var lastDown = 0L
var clickCount = 0
view.setOnTouchListener {v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
val downTime = System.currentTimeMillis()
clickCount++
if (lastDown > 0 && downTime - lastDown < 300 && clickCount == 2) {
//double clicks happens here
clickCount = 0
}
lastDown = downTime
}
MotionEvent.ACTION_UP -> {
CoroutineScope(Dispatchers.IO).launch {
//in case clickCount goes beyond than 1, here set it to 1
val upTime = System.currentTimeMillis()
if (upTime - lastDown <= 300 && clickCount > 0) {
clickCount = 1
}
delay(300)
if (System.currentTimeMillis() - lastDown > 300 && clickCount == 1) {
withContext(Dispatchers.Main) {
//single click happens here
}
clickCount = 0
}
}
}
}
true
}