I am trying to catch double-tap events using OnTouchListener. I figure I would set a long for motionEvent.ACTION_DOWN, and a different long for a second motionEvent.ACTION_D
Here is my solution.
It was important for me to have a fast and clear separation of 'single tap' and 'double tap'.
I tried GestureDetector
first but had very bad results. Maybe a result of my nested use of scrollviews - who knows...
I focus on MotionEvent.ACTION_UP
and the ID of the tapped element. To keep the first tap alive I use a Handler
sending a delayed message (350ms) so the user has some time to place its second tap on the ImageView
. If the user placed a second tap on an element with the identical id I take this as double tap, remove the delayed message and rund my custom code for 'double tap'. If the user placed a tap on an element with a different ID I take this as new tap and create another Handler
for it.
Class global variables
private int tappedItemId = -1;
Handler myTapHandler;
final Context ctx = this;
Code example
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;
}
});