Question

I have a problem with GoogleMap API for Android component MyLocationOverlay. I want to turn off MyLocationOverlay auto-recenter feature (to current user location) every time device location changes (and user location goes out of the visible part or the map).

It seems there is no flag to turn off the undesired maps auto-center feature when user location goes out of the screen

e.g.

public class LocationTest extends MapActivity{

  private MapView map;
  private MapController controller;

  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    map = (MapView) findViewById(R.id.map);
    final MyLocationOverlayUpdate overlay = new MyLocationOverlayUpdate(this, map);
    overlay.enableMyLocation();
    map.getOverlays().add(overlay);
  }

  @Override
  protected boolean isRouteDisplayed() {
    return false;
  }
}

public class MyLocationOverlayUpdate extends MyLocationOverlay {

  public MyLocationOverlayUpdate(Context context, MapView mapView) {
    super(context, mapView);
  }

  public void drawMyLocation(Canvas canvas, MapView mapView, 
              Location location, GeoPoint geoPoint, long when) {}
}

I looked through the net for this problem but didn't found the solution provided.

Additional info found:

  • I guess that documentation is faulty, buggy, or just outdated saying:

    Optionally, the constructor can also take a MapController and use it to keep the "my location" dot visible by panning the map when it would go offscreen

because there is no constructor accepting MapController as an argument, and it seems that I have no choice over keeping the "my location" dot visible or not.

  • I accidentaly found a workaround by overriding method drawMyLocation() with no call to super.drawMyLocation() solves the problem of recentering the map (undesired "feature" turns off). However i have to reimplement drawMyLocation() method, therefore changing default appearence (and spending time...)

Maybe there is a more clear solution?

Was it helpful?

Solution

extend MyLocationOverlay class and reimplement the overlay animation by overriding drawMyLocation method.

public class CustomMyLocationOverlay extends MyLocationOverlay {

    private static final String TAG = "Bankomatai";


    private Drawable[] slips;
    private final MapView mapView;
    private int currSlip = 0;
    private Location savedFix = null;
    Point point = new Point();
    Rect rect = new Rect();
    private Handler handler = new Handler();
    private Runnable overlayAnimationTask;


    public CustomMyLocationOverlay(Context context, MapView mapView) {
        super(context, mapView);
        this.mapView = mapView;
        slips = new Drawable[4];
        slips[0] = context.getResources().getDrawable(R.drawable.ic_maps_indicator_current_position_1);
        slips[1] = context.getResources().getDrawable(R.drawable.ic_maps_indicator_current_position_2);
        slips[2] = context.getResources().getDrawable(R.drawable.ic_maps_indicator_current_position_3);
        slips[3] = context.getResources().getDrawable(R.drawable.ic_maps_indicator_current_position_4);
        overlayAnimationTask = new Runnable() {

        @Override
        public void run() {
            currSlip = (currSlip + 1) % slips.length;
            CustomMyLocationOverlay.this.mapView.invalidate();
            handler.removeCallbacks(overlayAnimationTask);
            handler.postDelayed(overlayAnimationTask, 200);

        }

        };
        handler.removeCallbacks(overlayAnimationTask);
        handler.postAtTime(overlayAnimationTask, 100);
    }



    protected void drawMyLocation(Canvas canvas, MapView mapView, Location lastFix, GeoPoint myLocation, long when) {   
        Log.v(TAG, "draw: " + System.currentTimeMillis());      
        mapView.getProjection().toPixels(myLocation, point);
        rect.left = point.x - slips[currSlip].getIntrinsicWidth() / 2;
        rect.top = point.y - slips[currSlip].getIntrinsicHeight() / 2;
        rect.right = point.x + slips[currSlip].getIntrinsicWidth() / 2;
        rect.bottom = point.y + slips[currSlip].getIntrinsicHeight() / 2;
        slips[currSlip].setBounds(rect);
        slips[currSlip].draw(canvas);
    }
}

plus you need to create 4 icons and put them in res/drawable folder under names ic_maps_indicator_current_position_1, ic_maps_indicator_current_position_2, ic_maps_indicator_current_position_3, ic_maps_indicator_current_position_4. You need to draw them by yourself.

OTHER TIPS

public class CustomMyLocationOverlay extends MyLocationOverlay {
 @Override
     protected void drawMyLocation(Canvas canvas, MapView mapView, Location location,
             GeoPoint geoPoint, long when) {
         if (!recenter) {
             mapView.getController().stopAnimation(false);
         }

         // Now draw the location overlay.
         super.drawMyLocation(canvas, mapView, location, geoPoint, when);
     }
}

The recenter of the map when location changes uses the same logic as the map animation,so by stopping the animation,I was able to stop the re-centering of the map.Hope it help you. It worked for me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top