开发者

Android Map Overlay Issues

Is there any way i can implement a zoom listener that can trigger events as soon as the zoom level changes. So far, i have managed with the onUserinteraction method manually checking for changing zoom-level. Another thing is i to want add/remove overlays dynamically. what i,ve done so far is in the onUserinteraction method, i call a function which adds the overlays dynamically, using mapOverlays.add() function and the addition actually does happen dynamically. But somehow mapOverlays.remove() function is not removing the overlays

     //Function for adding first set of markers
     pub开发者_如何学Pythonlic void setOverlay()
{
    worldLength = World.length;
    mapOverlays = mapView.getOverlays();
    drawable0 = this.getResources().getDrawable(R.drawable.marker);
    itemizedOverlay0 = new MyItemizedOverlay(drawable0);
    for (int i = 0; i < worldLength; i++)
    {
        itemizedOverlay0.addOverlay(World[i]);
    }
    mapOverlays.add(itemizedOverlay0);
    mapView.postInvalidate();
}
     //Function for adding second set of markers
     public void setOverlay1() 
     {
      mapView.setStreetView(true);
      usaLength = USA.length;
      mexicoLength = Mexico.length;
               mapOverlays = mapView.getOverlays();
        drawable1 = this.getResources().getDrawable(R.drawable.marker);
        itemizedOverlay1 = new MyItemizedOverlay(drawable1);
        itemizedOverlay2 = new MyItemizedOverlay(drawable1);


        for (int i = 0; i < usaLength; i++) {
            itemizedOverlay1.addOverlay(USA[i]);
        }
        for (int i = 0; i < mexicoLength; i++) {
            itemizedOverlay2.addOverlay(Mexico[i]);
        }

        mapOverlays.add(itemizedOverlay1);
        mapOverlays.add(itemizedOverlay2);


    mapView.postInvalidate();

}

     public void onUserInteraction() {
   super.onUserInteraction();
   if(mapView.getZoomLevel()>3)
   {
       mapOverlays.remove(itemizedOverlay0);
       setOverlay1();
                 //the above happens
   }
   else if(mapView.getZoomLevel()<=3 && mapOverlays.size()>5)
   {
       mapOverlays.remove(itemizedOverlay1);
       mapOverlays.remove(itemizedOverlay2);
                 //the above doesn't
       setOverlay();   
   }
   else if(mapView.getZoomLevel()<=3)
   {

   }
}


In order to implement your custom zoom handler and add a listener, you need to be create your subclass of the MapView. First, let's create the interface for the OnZoomListener. Note that you could change the interface to suit your need, the following is just a skeleton code for you to start with


public interface OnZoomListener {
    /***
     * /**
     * Called when there is a zoom changes 
     * @param mapView Reference to the current map view
     * @param currentZoom The current zoom, set to -1 initially
     * @param newZoom The new zoom level
     */
     public void onZoomChanged(MapView mapView, int currentZoom, int newZoom);
}

Now, you need a subclass that will call this OnZoomListener whenever the zoom changes. Here is the skeleton code for that which is an extension of this SO Answer


public class MyMapView extends MapView {
    int oldZoomLevel=-1;
    OnZoomListener onZoomListener;

    public MyMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyMapView(Context context, String apiKey) {
        super(context, apiKey);
    }

    public void setOnZoomListener(OnZoomListener onZoomListener) {
        this.onZoomListener = onZoomListener;
    }

    @Override
    public void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        int newZoom = this.getZoomLevel();

        if (newZoom != oldZoomLevel) {
            // dispatch the listeners
            if(oldZoomLevel != -1 &&  onZoomListener != null) {
                onZoomListener.onZoomChanged(this, oldZoomLevel, newZoom);
            }

            // update the new zoom level
            oldZoomLevel = getZoomLevel();
        }
    }
}

Now you could use MyMapView in your layout instead of the standard MapView. Note: The code package com.so4729255 is what I use for testing only.


  <com.so4729255.MyMapView
                android:id="@+id/mapview"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:enabled="true"
                android:apiKey="YOUR API KEY"
                android:clickable="true"
        />

And finally add the OnZoomListener in your code. The code below just show the Toast for illustration of usage, you could do whatever you need to do there


 MyMapView mapView = (MyMapView)this.findViewById(R.id.mapview);
        mapView.setOnZoomListener(new OnZoomListener() {
            public void onZoomChanged(MapView mapView, int currentZoom,
                    int newZoom) {
                // implement your handler here
                Toast t = Toast.makeText(WebViewMain.this, "Zoom has changed from " + currentZoom + " to " + 
                        newZoom, 500);
                t.show();
            }
        });

As for your second question, as everyone has answered, calling MapView.invalidate() should repaint the map with its new state as it will force the View to redraw per the API documentation


well you have to refresh the map using

mapview.invalidate()

postInvalidate posts an invalidate request on the UI-thread, while a call to invalidate() invalidates the View immediately


When the zoom level changes, the map is redrawn so I simply put this type of functionality in my overlay's draw method, like so:

e@Override
public void draw(Canvas canvas, MapView mapv, boolean shadow)
{       
    int zoom = mapv.getZoomLevel();

    switch(zoom)
    {
        case 19:
            setMarkersForZoomLevel19();
            break;
        case 18:
            setMarkersForZoomLevel18();
            break;
        case 17:
            setMarkersForZoomLevel17();
            break;
        case 16:
            setMarkersForZoomLevel16();
            break;
        default:
            // Hide the markers or remove the overlay from the map view.                
            mapv.getOverlays().clear();
    }       

    // Putting this call here rather than at the beginning, ensures that
    // the Overlay items are drawn over the top of canvas stuff e.g. route lines.
    super.draw(canvas, mapv, false);        
}

and when you remove an overlay, remember to call mapView.invalidate().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜