myLocationOverlay change the marker

笑着哭i 提交于 2019-11-27 13:50:03

Step #1: Create a subclass of MyLocationOverlay.

Step #2: Override drawMyLocation() and draw the marker however you like. Bear in mind that this method not only draws the marker, but "if the user's position moves near the edge of the screen, and we've been given a MapController in our constructor, we'll scroll to recenter the new reading".

Thx @CommonsWare, you led me in the right direction. Spent quite a wile twiddling with this. The Javadoc on http://code.google.com/android/add-ons/google-apis/reference/com/google/android/maps/MyLocationOverlay.html is just wrong (or outdated) and messes with your brain where it says:

drawMyLocation

Also, if the user's position moves near the edge of the screen, and we've been given a MapController in our constructor, we'll scroll to recenter the new reading.

This is completely wrong. First, there is no such constructor in the class. Second of all, drawMyLocation only gets called when the current Location is within the viewbounds, or the screen is moved. So if you receive a new location and you don't see the marker at this moment, it won't be redrawn. Which is a good thing in general, but a bad thing if you want to implement mc.animateTo in the method to keep the location centered.

Third of all, you shouldn't need to pass a MapController, to enable currentLocation, because you already have the mapView and get the controller from it..

So I ended up writing my own Class that keeps centering on the current location once the location reaches the border of the mapView or is off-screen:

public class CurrentLocationOverlay extends MyLocationOverlay {

  // TODO: use dynamic calculation?
  private final static int PADDING_ACTIVE_ZOOM     = 50;

  private MapController    mc;
  private Bitmap           marker;
  private Point            currentPoint            = new Point();

  private boolean          centerOnCurrentLocation = true;

  private int              height;
  private int              width;

  /**
   * By default this CurrentLocationOverlay will center on the current location, if the currentLocation is near the
   * edge, or off the screen. To dynamically enable/disable this, use {@link #setCenterOnCurrentLocation(boolean)}.
   *
   * @param context
   * @param mapView
   */
  public CurrentLocationOverlay(Context context, MapView mapView) {
    super(context, mapView);
    this.mc = mapView.getController();
    this.marker = BitmapFactory.decodeResource(context.getResources(), R.drawable.position);
  }

  @Override
  protected void drawMyLocation(Canvas canvas, MapView mapView, Location lastFix, GeoPoint myLocation, long when) {
    // TODO: find a better way to get height/width once the mapView is layed out correctly
    if (this.height == 0) {
      this.height = mapView.getHeight();
      this.width = mapView.getWidth();
    }
    mapView.getProjection().toPixels(myLocation, currentPoint);
    canvas.drawBitmap(marker, currentPoint.x, currentPoint.y - 40, null);
  }

  @Override
  public synchronized void onLocationChanged(Location location) {
    super.onLocationChanged(location);
    // only move to new position if enabled and we are in an border-area
    if (mc != null && centerOnCurrentLocation && inZoomActiveArea(currentPoint)) {
      mc.animateTo(getMyLocation());
    }
  }

  private boolean inZoomActiveArea(Point currentPoint) {
    if ((currentPoint.x > PADDING_ACTIVE_ZOOM && currentPoint.x < width - PADDING_ACTIVE_ZOOM)
        && (currentPoint.y > PADDING_ACTIVE_ZOOM && currentPoint.y < height - PADDING_ACTIVE_ZOOM)) {
      return false;
    }
    return true;
  }

  public void setCenterOnCurrentLocation(boolean centerOnCurrentLocation) {
    this.centerOnCurrentLocation = centerOnCurrentLocation;
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!