androidandroid-mapviewandroid-mapsandroid-overlay

Zoom and onTap in MapView are mixing, how to solve it?


I got a MapView in my app. I got many OverlayItems in it with a little drawable mark.

If i touch an overlayitem, the onTap() method runs, and i get a little dialog. It is works nice, but sometimes when i try to zoom with multitouch, and my finger is atop of an overlayitem, the dialog comes up after i finished zooming. It is kinda buggy, because it is not so ergonomical, because you have to close the upcoming dialog after you zoomed.

How should i prevent my app from this event ? I dont want onTap() to run when im zooming at all.

I tried it with onTouch events and with 2 booleans but not working:

  @Override
    public boolean onTouchEvent(MotionEvent event, MapView mapView) {

         int action = event.getAction() & MotionEvent.ACTION_MASK;

         switch (action) {
                case MotionEvent.ACTION_DOWN: {
                    actionIsDown= true;
                    break;
                }

                case MotionEvent.ACTION_POINTER_DOWN: {

                    pointerIsDown=true;
                        break;
                }
                case MotionEvent.ACTION_POINTER_UP: {

                    pointerIsDown= false;
                        break;
                }
                case MotionEvent.ACTION_UP: {

                    actionIsDown= false;
                        break;
                }
         }


        return super.onTouchEvent(event, mapView);
    }

And the onTap:

    @Override
    protected boolean onTap(int index) 
    {



            if(pointerIsDown==false && actionIsDown==false){ //...dialog here

Any ideas?


Solution

  • Your code isn't working because the onTap() is fired when a MotionEvent.ACTION_POINTER_UPor MotionEvent.ACTION_UP occurs, and not MotionEvent.ACTION_POINTER_DOWNor MotionEvent.ACTION_DOWN.

    To test it correctly you need to check during UP action if the movement was used to zoom the map, and then save it to the boolean.

    Example code:

    Geopoint center = new Geopoint(0,0);
    Boolean ignoreTap = false;
    
    @Override
    public boolean onTouchEvent(MotionEvent event, MapView mapView) {
    
         int action = event.getAction() & MotionEvent.ACTION_MASK;
    
         switch (action) {
                case MotionEvent.ACTION_POINTER_DOWN: {
                case MotionEvent.ACTION_DOWN: {
                    center = mapView.getMapCenter();
                    ignoreTap = false;
                    break;
                }
    
                case MotionEvent.ACTION_UP: {
                case MotionEvent.ACTION_POINTER_UP: {
                      if(center != mapView.getMapCenter())
                        ignoreTap = true;
                      break;
                }
         }
        return super.onTouchEvent(event, mapView);
    }
    

    and in onTap():

    @Override
    protected boolean onTap(int index) 
    {
            if(!ignoreTap){ //...dialog here
    

    Note: I´m using the map center to test the zoom, as the multitouch zoom works arround the map point located between fingers center, resulting on a center change when you zoom. You couls also use the map longitude span.