There is a built-in GestureDetector that is able to "catch" all common interactions between the device and the user, including double tap. However to set it up for a single View, or a selection of Views, you have to do a bit of grunt work. I'll post the code of my test activity now:
public class MainActivity extends Activity implements OnClickListener {
private GestureDetector gd;
View.OnTouchListener otl;
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onDoubleTap(MotionEvent e) {
Toast.makeText(getApplicationContext(), "Test", Toast.LENGTH_SHORT).show();
return true;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gd = new GestureDetector(this, new MyGestureDetector());
otl = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return gd.onTouchEvent(event);
}
};
LinearLayout cotainerView = (LinearLayout) findViewById(R.id.container);
TextView tvNormal = new TextView(this);
tvNormal.setText("Normal text view");
tvNormal.setHeight(50);
DoubleTapTextView tvDoubleTap = new DoubleTapTextView(this);
tvDoubleTap.setText("Double tap text view");
tvDoubleTap.setHeight(50);
tvDoubleTap.setOnClickListener(this);
tvDoubleTap.setOnTouchListener(otl);
containerView.addView(tvNormal);
containerView.addView(tvDoubleTap);
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
So the trick is to pass the onTouch event, as well as its argument (MotionEvent e
) to your custom GestureListener. This way, every Gesture (Touch event) will be listened for, but your custom listener will execute onDoubleTap(MotionEvent e)
method only in the case the gesture is double tap. Hopefully, you understand the idea behind this, and as a treat, I'm posting a screenshot of the app running in an emulator to show you that the event is actually caught :)
EDIT: Here are the key points of the solution
Activity implements OnClickListener
Register the desired View for both
OnClickLister
andOnTouchListener
tvDoubleTap.setOnClickListener(this); //Your activity implements OnClickListener tvDoubleTap.setOnTouchListener(otl); //The wrapper listener from which you call your custom one
Inside the basic OnTouchListener, pass the argument to your custom GestureListener
@Override public boolean onTouch(View v, MotionEvent event) { return gd.onTouchEvent(event); }
Inside your custom GestureListener's
onDoubleTap(MotionEvent e)
method, implement your solution.class MyGestureDetector extends SimpleOnGestureListener { @Override public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "Test", Toast.LENGTH_SHORT).show(); return true; } }
Credits: Thanks to gav, for his research on his question