Search code examples
androidmapszoomingandroid-mapviewanimated

android mapview icons in wrong location when zoomed out


I'm trying to figure out why my icons are showing up over the ocean when I zoom out of my mapview but when I zoom in the points are correct.

Here is my code:

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);

    mapView = (MapView) findViewById(R.id.mapview1);
    mapView.setBuiltInZoomControls(true);
    MapController mapController = mapView.getController();

    //set up test points
    point = new GeoPoint(25982160, -80358564);
    showAnimatedMarker(point, "true");  
    point = new GeoPoint(34023084, -84781697);
    showAnimatedMarker(point, "Test");
    point = new GeoPoint(40759508, -73987061);
    showAnimatedMarker(point, "Yo YO YO");
    point = new GeoPoint(34152852, -118336107);
    showAnimatedMarker(point, "Boom shakalaka");
    point = new GeoPoint(-23564595, -46652759);
    showAnimatedMarker(point, "Testing having a real long name");

    mapController.setZoom(4);
    mapController.animateTo(point);
}

public void showAnimatedMarker(GeoPoint point, String locationName)
{
    //animate the marker
    RelativeLayout v = (RelativeLayout) View.inflate(this, R.layout.markerlayout, null);
    final ImageView marker = (ImageView) v.findViewById(R.id.marker);
    final TextView markerText = (TextView) v.findViewById(R.id.markerText);
    final String locName = locationName;
    marker.post(new Runnable() {
        @Override
        public void run() {
            markerText.setText(locName);
            AnimationDrawable markerImage = (AnimationDrawable)marker.getDrawable();            
            markerImage.start();
        }
    });
    mapView.addView(v, 0, new MapView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, point, MapView.LayoutParams.BOTTOM_CENTER));

}

Here is 2 pictures that show what I mean, 1 is zoomed out and 1 is zoomed into the California location.

Any help will be greatly appreciated.

Zoomed In Image

Zoomed Out Image

Edited:

Here is my updated code (I didn't include the myOverlays class because it is exactly what Frohnzie posted)

    MapController mapController = mapView.getController();
    MyOverlay testOverlay;

     //set up test points
    point = new GeoPoint(25982160, -80358564);
    //showAnimatedMarker(point, "true");
    testOverlay = new MyOverlay(this,  mapView, point);
    mapOverlays.add(testOverlay);       

    point = new GeoPoint(34023084, -84781697);
    //showAnimatedMarker(point, "Test");
    testOverlay = new MyOverlay(this,  mapView, point);
    mapOverlays.add(testOverlay);   

    point = new GeoPoint(40759508, -73987061);
    //showAnimatedMarker(point, "Yo YO YO");
    testOverlay = new MyOverlay(this,  mapView, point);
    mapOverlays.add(testOverlay);   

    point = new GeoPoint(34152852, -118336107);
    //showAnimatedMarker(point, "Boom shakalaka");
    testOverlay = new MyOverlay(this,  mapView, point);
    mapOverlays.add(testOverlay);   

    point = new GeoPoint(-23564595, -46652759);
    //showAnimatedMarker(point, "Testing having a real long name");
    testOverlay = new MyOverlay(this,  mapView, point);
    mapOverlays.add(testOverlay);   

    mapController.setZoom(4);
    mapController.animateTo(point);
    mapView.invalidate();
}

Solution

  • Have you considered using the overly feature? The following overlay will animate a marker on the map. For multiple markers you could use extend OverlayItem.

    public class MyOverlay extends Overlay {
      private Drawable mMarker;
      private MapView mMapView;
      private int level;
      private Timer timer;
      Private GeoPoint mGeoPoint;
    
      public MyOverlay(Context context, MapView mapView, GeoPoint geoPoint) {
        mMapView = mapView;
        mGeoPoint = geoPoint;
        mMarker = context.getResources().getDrawable(R.drawable.position_anim);
        timer = new Timer();
        timer.schedule(new TimerTask() {
          @Override
          public void run() {
            level = (level + 1) % 2;
            mMapView.postInvalidate();
          }
        }, 1000, 1000);
      }
    
      @Override
      public void draw(Canvas canvas, MapView mapView, boolean shadow) {
        Projection projection = mapView.getProjection();
        Point center = new Point();
        projection.toPixels(mGeoPoint, center);
    
        int width = mMarker.getIntrinsicWidth();
        int height = mMarker.getIntrinsicHeight();
    
        mMarker.setLevel(level);
        mMarker.setBounds(center.x - width / 2, center.y - height / 2, center.x + width / 2, center.y + height / 2);
        mMarker.draw(canvas);
      }
    }
    

    Example marker resource (position_anim.xml):

    <level-list xmlns:android="http://schemas.android.com/apk/res/android" >
      <item android:maxLevel="0" android:drawable="@drawable/image1" />
      <item android:maxLevel="1" android:drawable="@drawable/image2" />
    </level-list>