Most of the Android UI elements already come with some easy way to detect and handle touch events. For example have a look to the following code:
TextView myTextView = (TextView) findViewById(R.id.myTextView); myTextView.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { Log.i("MyExample", "A Long Click has been detected"); return true; } });
When you touch the myTextView long enough, you will see in the logs the print A Long Click has been detected.
In other cases, however, in which this kind of solution is not available, or doesn’t fit your needs. For example
- the UI element does not let you set a listener for the action you want to detect. You can’t set a double click listener for a
TextViewwidget, and other elements, like the Map Overlay, can only detect a very limited set of actions; - you need more information about the action, e.g. the exact position of the pointer (finger).
In those cases the best solution is to use the GestureDetector.
The GestureDetector works a little bit differently from what you may be used to. In fact it is not listening to the actions: it is in charge of translating what a widget or another UI element sees as a generic touch event, to a more specific action. Fortunately any UI element gives you some way to handle a generic touch event.
Let’s see a complete example of how to put the GestureDetector to work within a simple Activity class.
package com.example; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; public class GestureDetectorExample extends Activity { static private String TAG = "GestureDetectorExample"; private GestureDetector mGestureDetector; private TextView mTextView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTextView = (TextView) findViewById(R.id.myTextView); mTextView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return mGestureDetector.onTouchEvent(event); } }); mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() { @Override public void onLongPress(MotionEvent e) { Log.d(TAG, "Long Press event"); } @Override public boolean onDoubleTap(MotionEvent e) { Log.d(TAG, "Double Tap event"); return true; } @Override public boolean onDown(MotionEvent e) { return true; } }); mGestureDetector.setIsLongpressEnabled(true); } }
Let’s see now what happens in the example:
- a
TouchListeneris set for theTextView; - a
GestureDetectorobject is instantiated, with a reference to an object which implements theOnGestureListenerinterface (we’ll come back on this later); - when a touch event is detected by the
TextView, the methodonTouchis called; - the method
onTouchcalls theGestureDetectorand pass it theMotionEvent, an object containing the information needed by theGestureDetectorto recognize the different touch events; - the
GestureDetectoruses theMotionEventobject to identify the touch events; - once identified the type of the event, the
GestureDetectorcalls the appropriate method of theOnGestureListener(double tap, long press, etc.).
It’s time to run the program and perform some long tap, or double click on the TextView while keeping an eye on the logs in the LogCat.

A couple of notes.
- The
onDownmethod.
If you try to remove it you will see that theonDoubleTapmethod is not called anymore. Same if theonDownmethod returnsfalse. So keep in mind that to makeonDoubleTapwork you must have aonDownmethod returning true. SimpleOnGestureListenerclass vsOnGestureListenerinterface
In the example, theSimpleOnGestureListenerclass is used. It is a commodity class that implements theOnGestureListenerinterface. If you decide to implement theOnGestureListenerinterface you must implement all its methods, even you only need to handle one event. When you inherit from theSimpleOnGestureListener, instead, you will only override the methods you need.
Let’s now see another example, this time using the Overlay from the Google Maps API.
package com.example; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import com.google.android.maps.MapActivity; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; public class GestureDetectExampleMap extends MapActivity { private static String TAG = "GestureDetectorExampleMap"; MapView mMapView; GestureDetector mGestureDetector; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mMapView = (MapView) findViewById(R.id.MapView); mMapView.getOverlays().add(new Overlay() { @Override public boolean onTouchEvent(MotionEvent e, MapView mapView) { mGestureDetector.onTouchEvent(e); return super.onTouchEvent(e, mapView); } }); mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() { @Override public void onLongPress(MotionEvent e) { Log.d(TAG, "Long Press event"); } @Override public boolean onDoubleTap(MotionEvent e) { Log.d(TAG, "Double Tap event"); return true; } @Override public boolean onDown(MotionEvent e) { return true; } }); } @Override protected boolean isRouteDisplayed() { return false; } }
The GestureDetector part is exactly the same, but in this case the GestureDetector.onTouchEvent is called by the map Overlay, and unlike a generic View element, there is no need to instantiate a Listener for it.
A touch event will go through the following steps:
- the touch event triggers the
onTouchEventinside theOverlay; - the
onTouchEventof theOverlaycalls the correspondent method of theGestureDetectorand pass it theMotionEvent, an object containing the information needed by theGestureDetectorto recognize the different touch events; - the
GestureDetectoruses theMotionEventobject to identify the touch events; - once identified the type of the event, the
GestureDetectorcalls the appropriate method of theOnGestureListener(double tap, long press, etc.).
For lazy people only: download a zip file with the two examples.
It may be useful for you to have a look to a few articles that I also consulted before writing this article:
- android maps: How to Long Click a Map?
- Android onFling not responding
- Some classes from the raveneye project on Google Code.
- I don’t like using big libraries when I only need one specific function or behavior. If you disagree and you are working with maps and overlays, you may like to have a look at the mapview-overlay-manager project. However I’m quite sure you won’t need extra help after this article.
Feel free to comment to ask any question, correct any mistake or suggest any improvement.
I recently bought an iPod Touch, very nice gadget, but with a very bad video section: only a few formats accepted, forcing me to recode almost all my video files.
I also prepared a few lines script to encode your videos from the Nautilus file manager. The result videos will be placed into your Desktop. Just place the Nautilus Scripts 


linux