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().
精彩评论