Wednesday, August 29, 2012

Detect onDoubleTap or onLongPress on a MapView

In this article you will learn how a long click or a double click can be detected on a MapView object.

If your application uses a MapView from Google APIs, you could be interested in how to detect some simple gestures like a double tap (double click) or a long tap (long click).

As you probably know already, you have to use ItemizedOverlay subclass to work with tap events on a MapView.  Sadly ItemizedOverlay provides only onTouchEvent(MotionEvent) and onTap(int), which can be a little bit challenging to use for detecting more complex events.

Fortunately, the solution is quite simple as we can use GestureDetector and SimpleOnGestureListener. Following code sample shows, how to do it quite simply:

  // Overlay
  private class Overlays extends ItemizedOverlay {
    private ArrayList<overlayitem> overlays = new ArrayList<overlayitem>();

    private GestureDetector gestureDetector;

    //Private MapGestureListener which will listen to just
    //a long and a double press
    private class MapGestureListener extends SimpleOnGestureListener {
      @override
      public void onLongPress(MotionEvent _motion) {
        //Do something nice here
      }

      @override
      public boolean onDoubleTap(MotionEvent _motion) {
      //Do something nice here
       return true;
      }
    }
    //ItemizedOverlay constructor. Register GestureDetector and 
    //MapGestureListener right here
    public Overlays(Drawable defaultMarker) {
      super(boundCenterBottom(defaultMarker));
      gestureDetector = new GestureDetector(GApp.context,
          new MapGestureListener());
    }
    //onTap() method should work normally
    @Override
    public boolean onTap(int _index) {
      Toast.makeText(GApp.context, overlays.get(_index).getTitle(),
          Toast.LENGTH_SHORT).show();
      return true;
    }
    //Ship onTouchEvent to our GestureDetector and return what it returns
    @Override
    public boolean onTouchEvent(MotionEvent _motion, MapView _mapView) {
      return gestureDetector.onTouchEvent(_motion);
    }
  }

Hope this will work for you.