myLocationOverlay изменить маркер
Как изменить синий анимированный маркер по умолчанию для MyLocationOverlay на картах Google?
2 ответа
Шаг № 1: Создайте подкласс MyLocationOverlay
,
Шаг № 2: переопределить drawMyLocation()
и нарисуйте маркер, как вам нравится. Имейте в виду, что этот метод не только рисует маркер, но и "если позиция пользователя перемещается ближе к краю экрана, и нам дали MapController
в нашем конструкторе мы прокручиваем, чтобы переназначить новое чтение ".
Спасибо @CommonsWare, вы привели меня в правильном направлении. Потратил довольно коварный трюк с этим. Javadoc на http://code.google.com/android/add-ons/google-apis/reference/com/google/android/maps/MyLocationOverlay.html просто неверен (или устарел) и портит ваш мозг, где он говорит:
drawMyLocation
Кроме того, если позиция пользователя перемещается ближе к краю экрана, и в нашем конструкторе нам был присвоен MapController, мы прокручиваем, чтобы переназначить новое чтение.
Это совершенно неправильно. Во-первых, в классе нет такого конструктора. Во-вторых, drawMyLocation вызывается только тогда, когда текущее местоположение находится в пределах видимости или когда экран перемещается. Поэтому, если вы получите новое местоположение и не увидите маркер в данный момент, он не будет перерисован. Что в целом хорошо, но плохо, если вы хотите реализовать в методе mc.animateTo, чтобы сохранить расположение в центре.
В-третьих, вам не нужно передавать MapController, чтобы включить currentLocation, потому что у вас уже есть mapView и вы получаете контроллер из него.
Итак, я закончил писать свой собственный класс, который центрируется на текущем местоположении, как только местоположение достигает границы mapView или находится вне экрана:
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;
}
}