[android] #3276 - View annotation integration in Marker

This commit is contained in:
Tobrun
2016-05-18 09:45:56 +02:00
committed by Tobrun
parent 9b3a6c3a1b
commit c3aeb9facc
9 changed files with 441 additions and 244 deletions

View File

@@ -18,6 +18,7 @@ public abstract class BaseMarkerOptions<U extends Marker, T extends BaseMarkerOp
protected String snippet;
protected String title;
protected Icon icon;
protected boolean markerView;
public T position(LatLng position) {
this.position = position;
@@ -39,8 +40,16 @@ public abstract class BaseMarkerOptions<U extends Marker, T extends BaseMarkerOp
return getThis();
}
public T markerView(boolean isMarkerView) {
this.markerView = isMarkerView;
return getThis();
}
public abstract T getThis();
public abstract U getMarker();
public boolean isViewMarker() {
return markerView;
}
}

View File

@@ -4,15 +4,16 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
/**
* Marker is an annotation that shows an icon image at a geographical location.
*
* <p>
* An {@link InfoWindow} can be shown when a Marker is pressed
* </p>
*/
public class Marker extends Annotation {
@@ -20,9 +21,14 @@ public class Marker extends Annotation {
private String snippet;
private Icon icon;
private String title;
private InfoWindow infoWindow = null;
private boolean infoWindowShown = false;
private InfoWindow infoWindow;
private boolean infoWindowShown;
private int topOffsetPixels;
private int rightOffsetPixels;
private boolean markerView;
/**
* Constructor
@@ -36,6 +42,7 @@ public class Marker extends Annotation {
snippet = baseMarkerOptions.snippet;
icon = baseMarkerOptions.icon;
title = baseMarkerOptions.title;
markerView = baseMarkerOptions.markerView;
}
public LatLng getPosition() {
@@ -50,6 +57,10 @@ public class Marker extends Annotation {
return title;
}
public boolean isViewMarker() {
return markerView;
}
/**
* Do not use this method. Used internally by the SDK.
*/
@@ -105,6 +116,10 @@ public class Marker extends Annotation {
this.title = title;
}
void setMarkerView(boolean isMarkerView){
markerView = isMarkerView;
}
/**
* Do not use this method. Used internally by the SDK.
*/
@@ -129,7 +144,7 @@ public class Marker extends Annotation {
}
private InfoWindow showInfoWindow(InfoWindow iw, MapView mapView) {
iw.open(mapView, this, getPosition(), 0, topOffsetPixels);
iw.open(mapView, this, getPosition(), rightOffsetPixels, topOffsetPixels);
infoWindowShown = true;
return iw;
}
@@ -148,6 +163,13 @@ public class Marker extends Annotation {
this.topOffsetPixels = topOffsetPixels;
}
/**
* Do not use this method. Used internally by the SDK.
*/
public void setRightOffsetPixels(int rightOffsetPixels) {
this.rightOffsetPixels = rightOffsetPixels;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View File

@@ -3,7 +3,6 @@ package com.mapbox.mapboxsdk.annotations;
import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import com.mapbox.mapboxsdk.geometry.LatLng;
@@ -38,7 +37,8 @@ public final class MarkerOptions extends BaseMarkerOptions<Marker, MarkerOptions
position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
snippet(in.readString());
title(in.readString());
if(in.readByte()!=0){
markerView(in.readByte() != 0);
if (in.readByte() != 0) {
// this means we have an icon
String iconId = in.readString();
Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
@@ -63,6 +63,7 @@ public final class MarkerOptions extends BaseMarkerOptions<Marker, MarkerOptions
out.writeString(getSnippet());
out.writeString(getTitle());
Icon icon = getIcon();
out.writeByte((byte) (markerView ? 1 : 0));
out.writeByte((byte) (icon != null ? 1 : 0));
if (icon != null) {
out.writeString(getIcon().getId());
@@ -86,6 +87,7 @@ public final class MarkerOptions extends BaseMarkerOptions<Marker, MarkerOptions
marker.setSnippet(snippet);
marker.setTitle(title);
marker.setIcon(icon);
marker.setMarkerView(markerView);
return marker;
}

View File

@@ -0,0 +1,160 @@
package com.mapbox.mapboxsdk.annotations;
import android.graphics.Point;
import android.graphics.PointF;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.AnimatorRes;
import android.support.annotation.NonNull;
public class MarkerViewSettings implements Parcelable {
private PointF centerOffset;
private Point infoWindowOffset;
private boolean flat;
private int animEnterRes;
private int animSelectRes;
private int animDeselectRes;
private int animExitRes;
MarkerViewSettings(PointF centerOffset, Point infoWindowOffset, boolean flat, int animEnterRes, int animSelectRes, int animDeselectRes, int animExitRes) {
this.centerOffset = centerOffset;
this.infoWindowOffset = infoWindowOffset;
this.flat = flat;
this.animEnterRes = animEnterRes;
this.animSelectRes = animSelectRes;
this.animDeselectRes = animDeselectRes;
this.animExitRes = animExitRes;
}
MarkerViewSettings(Parcel parcel) {
this.centerOffset = parcel.readParcelable(PointF.class.getClassLoader());
this.infoWindowOffset = parcel.readParcelable(Point.class.getClassLoader());
this.flat = parcel.readByte() != 0;
this.animEnterRes = parcel.readInt();
this.animSelectRes = parcel.readInt();
this.animDeselectRes = parcel.readInt();
this.animExitRes = parcel.readInt();
}
@NonNull
public PointF getCenterOffset() {
return centerOffset;
}
@NonNull
public Point getInfoWindowOffset() {
return infoWindowOffset;
}
public boolean isFlat() {
return flat;
}
@AnimatorRes
public int getAnimEnterRes() {
return animEnterRes;
}
@AnimatorRes
public int getAnimSelectRes() {
return animSelectRes;
}
@AnimatorRes
public int getAnimDeselectRes() {
return animDeselectRes;
}
@AnimatorRes
public int getAnimExitRes() {
return animExitRes;
}
public static final Parcelable.Creator<MarkerViewSettings> CREATOR
= new Parcelable.Creator<MarkerViewSettings>() {
public MarkerViewSettings createFromParcel(Parcel in) {
return new MarkerViewSettings(in);
}
public MarkerViewSettings[] newArray(int size) {
return new MarkerViewSettings[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(centerOffset, flags);
dest.writeParcelable(infoWindowOffset, flags);
dest.writeByte((byte) (flat ? 1 : 0));
dest.writeInt(animEnterRes);
dest.writeInt(animSelectRes);
dest.writeInt(animDeselectRes);
dest.writeInt(animExitRes);
}
/**
* Builder for composing LatLngBounds objects.
*/
public static final class Builder {
private PointF centerOffset;
private Point infoWindowOffset;
private boolean flat;
private int animEnterRes;
private int animSelectRes;
private int animDeselectRes;
private int animExitRes;
public Builder() {
centerOffset = new PointF();
infoWindowOffset = new Point();
}
public Builder centerOffset(float dx, float dy) {
centerOffset.offset(dx, dy);
return this;
}
public Builder infoWindowOffset(int dx, int dy) {
infoWindowOffset.offset(dx, -dy);
return this;
}
public Builder flat(boolean isFlat) {
flat = isFlat;
return this;
}
public Builder animEnterRes(@AnimatorRes int animatorRes) {
animEnterRes = animatorRes;
return this;
}
public Builder animSelectRes(@AnimatorRes int animatorRes) {
animSelectRes = animatorRes;
return this;
}
public Builder animDeselectRes(@AnimatorRes int animatorRes) {
animDeselectRes = animatorRes;
return this;
}
public Builder animExitRes(@AnimatorRes int animatorRes) {
animExitRes = animatorRes;
return this;
}
public MarkerViewSettings build() {
return new MarkerViewSettings(centerOffset, infoWindowOffset, flat, animEnterRes, animSelectRes, animDeselectRes, animExitRes);
}
}
}

View File

@@ -25,7 +25,6 @@ import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.CallSuper;
@@ -35,7 +34,6 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.LongSparseArray;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.ScaleGestureDetectorCompat;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
@@ -59,7 +57,6 @@ import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ZoomButtonsController;
import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;
@@ -98,7 +95,6 @@ import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
@@ -479,88 +475,15 @@ public class MapView extends FrameLayout {
if (mViewMarkersUpdateRunning || currentTime < mViewMarkerBoundsUpdateTime) {
return;
}
mViewMarkerBoundsUpdateTime = currentTime + 300;
mViewMarkersUpdateRunning = true;
List<Marker> inBounds = new ArrayList<>();
Map<Marker, View> outBounds = new HashMap<>();
mMapboxMap.invalidateViewMarkersInBounds();
LatLngBounds bounds = mMapboxMap.getProjection().getVisibleRegion().latLngBounds;
long[] ids = mNativeMapView.getAnnotationsInBounds(bounds);
LongSparseArray<View> markerViews = mMapboxMap.getMarkerViews();
Log.v(MapboxConstants.TAG, "Annotations in bounds: " + ids.length);
boolean found;
long key;
// introduce new markers
for (long id : ids) {
found = false;
for (int i = 0; i < markerViews.size(); i++) {
key = markerViews.keyAt(i);
if (id == key) {
found = true;
}
}
if (!found) {
Annotation annotation = mMapboxMap.getAnnotation(id);
if (annotation instanceof Marker) {
inBounds.add((Marker) annotation);
} else {
Log.v(MapboxConstants.TAG, "Not instance of Marker" + id);
}
} else {
Log.v(MapboxConstants.TAG, "Already added " + id);
}
}
// clean up out of bound markers
for (int i = 0; i < markerViews.size(); i++) {
found = false;
key = markerViews.keyAt(i);
for (long id : ids) {
if (id == key) {
found = true;
}
}
if (!found) {
Annotation annotation = mMapboxMap.getAnnotation(key);
if (annotation instanceof Marker) {
outBounds.put((Marker) annotation, markerViews.get(key));
} else {
Log.v(MapboxConstants.TAG, "Not instance of Marker" + key);
}
}
}
Result result = new Result(inBounds, outBounds);
mMapboxMap.setViewMarkersBoundsTaskResult(result);
mViewMarkersUpdateRunning = false;
Log.v(MapboxConstants.TAG, "Amount of child views " + getChildCount());
}
public class Result {
private List<Marker> inBounds;
private Map<Marker, View> outBounds;
public Result(List<Marker> inBounds, Map<Marker, View> outBounds) {
this.inBounds = inBounds;
this.outBounds = outBounds;
}
public List<Marker> getInBounds() {
return inBounds;
}
public Map<Marker, View> getOutBounds() {
return outBounds;
}
}
// }
/**
* You must call this method from the parent's {@link android.app.Activity#onSaveInstanceState(Bundle)}
* or {@link android.app.Fragment#onSaveInstanceState(Bundle)}.
@@ -970,7 +893,7 @@ public class MapView extends FrameLayout {
* <p>
* DEPRECATED @see MapboxAccountManager#getAccessToken()
* </p>
* <p>
* <p/>
* Returns the current Mapbox access token used to load map styles and tiles.
* </p>
*
@@ -1169,7 +1092,7 @@ public class MapView extends FrameLayout {
mNativeMapView.removeAnnotations(ids);
}
private List<Marker> getMarkersInBounds(@NonNull LatLngBounds bbox) {
List<Marker> getMarkersInBounds(@NonNull LatLngBounds bbox) {
if (mDestroyed || bbox == null) {
return new ArrayList<>();
}
@@ -1438,27 +1361,29 @@ public class MapView extends FrameLayout {
mCompassView.update(getDirection());
mMyLocationView.update();
LongSparseArray<View> viewMarkers = mMapboxMap.getMarkerViews();
for (int i = 0; i < viewMarkers.size(); i++) {
mViewHolder = viewMarkers.valueAt(i);
Map<Marker, View> viewMarkers = mMapboxMap.getMarkerViewMap();
for (Marker marker : viewMarkers.keySet()) {
mViewHolder = viewMarkers.get(marker);
if (mViewHolder != null) {
Marker marker = (Marker) mMapboxMap.getAnnotation(viewMarkers.keyAt(i));
if (marker != null) {
PointF point = mMapboxMap.getProjection().toScreenLocation(marker.getPosition());
mViewHolder.setX(point.x - (mViewHolder.getMeasuredWidth() / 2));
mViewHolder.setY(point.y - (mViewHolder.getMeasuredHeight() / 2));
PointF point = mMapboxMap.getProjection().toScreenLocation(marker.getPosition());
mViewHolder.setX(point.x - (mViewHolder.getMeasuredWidth() / 2));
mViewHolder.setY(point.y - (mViewHolder.getMeasuredHeight() / 2));
if (mViewHolder.getVisibility() == GONE) {
mViewHolder.animate().cancel();
mViewHolder.setAlpha(0);
mViewHolder.animate().alpha(1).setDuration(MapboxConstants.ANIMATION_DURATION_SHORT).setInterpolator(new FastOutSlowInInterpolator()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mViewHolder.setVisibility(VISIBLE);
}
}).start();
}
if (mViewHolder.getVisibility() == GONE) {
mViewHolder.animate().cancel();
mViewHolder.setAlpha(0);
mViewHolder.animate()
.alpha(1)
.setDuration(MapboxConstants.ANIMATION_DURATION_SHORT)
.setInterpolator(new FastOutSlowInInterpolator())
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mViewHolder.setVisibility(VISIBLE);
}
})
.start();
}
}
}
@@ -1756,7 +1681,7 @@ public class MapView extends FrameLayout {
if (annotation.getId() == newSelectedMarkerId) {
if (selectedMarkers.isEmpty() || !selectedMarkers.contains(annotation)) {
// only handle click if no marker view is available
if(mMapboxMap.getMarkerViews().get(annotation.getId())==null) {
if (mMapboxMap.getMarkerViewMap().get(annotation) == null) {
mMapboxMap.selectMarker((Marker) annotation);
}
}

View File

@@ -6,6 +6,8 @@ import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.PointF;
import android.location.Location;
import android.os.SystemClock;
import android.support.annotation.AnimatorRes;
@@ -31,6 +33,7 @@ import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.MarkerViewSettings;
import com.mapbox.mapboxsdk.annotations.Polygon;
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
import com.mapbox.mapboxsdk.annotations.Polyline;
@@ -49,6 +52,8 @@ import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@@ -74,15 +79,14 @@ public class MapboxMap {
private LongSparseArray<Annotation> mAnnotations;
private List<Marker> mSelectedMarkers;
private LongSparseArray<View> mMarkerViews;
private Map<Marker, View> mMarkerViewMap;
private LongSparseArray<MarkerViewSettings> mMarkerViewSettingsMap;
private List<InfoWindow> mInfoWindows;
private MapboxMap.InfoWindowAdapter mInfoWindowAdapter;
private OnMarkerViewClickListener mOnMarkerViewClickListener;
private int mMarkerViewItemAnimatorInRes;
private int mMarkerViewItemAnimatorOutRes;
private Bitmap mViewMarkerBitmap;
private Bitmap mViewMarkerBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
private boolean mMyLocationEnabled;
private boolean mAllowConcurrentMultipleInfoWindows;
@@ -112,10 +116,11 @@ public class MapboxMap {
mTrackingSettings = new TrackingSettings(mMapView, mUiSettings);
mProjection = new Projection(mapView);
mAnnotations = new LongSparseArray<>();
mMarkerViews = new LongSparseArray<>();
mMarkerViewAdapters = new ArrayList<>();
mSelectedMarkers = new ArrayList<>();
mInfoWindows = new ArrayList<>();
mMarkerViewMap = new HashMap<>();
mMarkerViewSettingsMap = new LongSparseArray<>();
}
//
@@ -648,86 +653,107 @@ public class MapboxMap {
// Annotations
//
void setViewMarkersBoundsTaskResult(MapView.Result result) {
Map<Marker, View> outBoundsMarker = result.getOutBounds();
void invalidateViewMarkersInBounds() {
List<Marker> markers = mMapView.getMarkersInBounds(mProjection.getVisibleRegion().latLngBounds);
Log.v(MapboxConstants.TAG, "Annotations in bounds: " + markers.size());
View convertView;
// out of bounds markers
for (Map.Entry<Marker, View> outBoundsEntry : outBoundsMarker.entrySet()) {
convertView = outBoundsEntry.getValue();
if (convertView != null) {
if (mMarkerViewItemAnimatorOutRes != 0) {
Animator animator = AnimatorInflater.loadAnimator(mMapView.getContext(), mMarkerViewItemAnimatorOutRes);
// remove old markers
Iterator<Marker> iterator = mMarkerViewMap.keySet().iterator();
while (iterator.hasNext()) {
Marker m = iterator.next();
if (!markers.contains(m)) {
// remove marker
convertView = mMarkerViewMap.get(m);
MarkerViewSettings settings = mMarkerViewSettingsMap.get(m.getId());
int deselectAnimRes = settings.getAnimDeselectRes();
if (deselectAnimRes != 0) {
Animator animator = AnimatorInflater.loadAnimator(mMapView.getContext(), deselectAnimRes);
animator.setDuration(0);
animator.setTarget(convertView);
animator.start();
}
removeMarkerView(outBoundsEntry.getKey().getId());
removeMarkerView(m);
iterator.remove();
}
}
// in bounds markers
List<Marker> inBoundsMarkers = result.getInBounds();
for (final Marker marker : inBoundsMarkers) {
Log.v("TAG", "Calling get view for " + marker.getId());
for (final MarkerViewAdapter adapter : mMarkerViewAdapters) {
if (adapter.getMarkerClass() == marker.getClass()) {
convertView = (View) adapter.getViewReusePool().acquire();
View adaptedView = adapter.getView(marker, convertView, mMapView);
if (adaptedView != null) {
// hack to hide old marker, todo replace with visibility
Icon icon = marker.getIcon();
if (!icon.getBitmap().equals(mViewMarkerBitmap)) {
if (mViewMarkerBitmap == null) {
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
mViewMarkerBitmap = Bitmap.createBitmap(icon.getBitmap().getWidth(), icon.getBitmap().getHeight(), conf);
// introduce new markers
for (final Marker marker : markers) {
if (marker.isViewMarker()) {
if (!mMarkerViewMap.containsKey(marker)) {
Log.v("TAG", "Calling get view for " + marker.getId());
for (final MarkerViewAdapter adapter : mMarkerViewAdapters) {
if (adapter.getMarkerClass() == marker.getClass()) {
if (mMarkerViewSettingsMap.get(marker.getId()) == null) {
mMarkerViewSettingsMap.put(marker.getId(), adapter.getMarkerViewSettings(marker));
}
marker.setIcon(IconFactory.recreate(icon.getId(), mViewMarkerBitmap));
}
if (mSelectedMarkers.contains(marker)) {
if (mMarkerViewItemAnimatorInRes != 0) {
Animator animator = AnimatorInflater.loadAnimator(mMapView.getContext(), mMarkerViewItemAnimatorInRes);
animator.setDuration(0);
animator.setTarget(convertView);
animator.start();
}
}
convertView = (View) adapter.getViewReusePool().acquire();
View adaptedView = adapter.getView(marker, convertView, mMapView);
adaptedView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// set user provided offset to view marker
final MarkerViewSettings markerViewSettings = mMarkerViewSettingsMap.get(marker.getId());
Point infoWindowOffset = markerViewSettings.getInfoWindowOffset();
marker.setTopOffsetPixels(infoWindowOffset.y);
marker.setRightOffsetPixels(infoWindowOffset.x);
boolean clickHandled = false;
if (mOnMarkerViewClickListener != null) {
clickHandled = mOnMarkerViewClickListener.onMarkerClick(marker, v, adapter);
}
if (!clickHandled) {
if (mMarkerViewItemAnimatorInRes != 0) {
Animator animator = AnimatorInflater.loadAnimator(mMapView.getContext(), mMarkerViewItemAnimatorInRes);
animator.setTarget(v);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
selectMarker(marker);
}
});
if (adaptedView != null) {
if (mSelectedMarkers.contains(marker)) {
// if a marker to be shown was selected
// replay that animation with duration 0
int selectAnimRes = markerViewSettings.getAnimSelectRes();
if (selectAnimRes != 0) {
Animator animator = AnimatorInflater.loadAnimator(mMapView.getContext(), selectAnimRes);
animator.setDuration(0);
animator.setTarget(convertView);
animator.start();
} else {
selectMarker(marker);
}
}
}
});
mMarkerViews.append(marker.getId(), adaptedView);
if (convertView == null) {
mMapView.addView(adaptedView);
adaptedView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean clickHandled = false;
if (mOnMarkerViewClickListener != null) {
clickHandled = mOnMarkerViewClickListener.onMarkerClick(marker, v, adapter);
}
if (!clickHandled) {
int enterAnimatorRes = markerViewSettings.getAnimSelectRes();
if (enterAnimatorRes != 0) {
Animator animator = AnimatorInflater.loadAnimator(mMapView.getContext(), enterAnimatorRes);
animator.setTarget(v);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
selectMarker(marker);
}
});
animator.start();
} else {
selectMarker(marker);
}
}
}
});
mMarkerViewMap.put(marker, adaptedView);
if (convertView == null) {
mMapView.addView(adaptedView);
}
}
}
}
} else {
//already added
Log.v(MapboxConstants.TAG, "Marker already added");
}
} else {
Log.v(MapboxConstants.TAG, "Marker is not a view marker");
}
}
}
@@ -1010,16 +1036,16 @@ public class MapboxMap {
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
marker.hideInfoWindow();
removeMarkerView(annotation.getId());
removeMarkerView(marker);
mMarkerViewMap.remove(marker);
}
long id = annotation.getId();
mMapView.removeAnnotation(id);
mAnnotations.remove(id);
}
private void removeMarkerView(long id) {
final View viewHolder = mMarkerViews.get(id);
final Marker marker = (Marker) getAnnotation(id);
private void removeMarkerView(Marker marker) {
final View viewHolder = mMarkerViewMap.get(marker);
if (viewHolder != null && marker != null) {
for (final MarkerViewAdapter<?> adapter : mMarkerViewAdapters) {
if (adapter.getMarkerClass() == marker.getClass()) {
@@ -1047,9 +1073,7 @@ public class MapboxMap {
});
}
}
}
mMarkerViews.remove(id);
}
/**
@@ -1075,8 +1099,10 @@ public class MapboxMap {
for (int i = 0; i < count; i++) {
Annotation annotation = annotationList.get(i);
if (annotation instanceof Marker) {
((Marker) annotation).hideInfoWindow();
removeMarkerView(annotation.getId());
Marker marker = (Marker) annotation;
marker.hideInfoWindow();
removeMarkerView(marker);
mMarkerViewMap.remove(marker);
}
ids[i] = annotationList.get(i).getId();
}
@@ -1098,8 +1124,10 @@ public class MapboxMap {
ids[i] = mAnnotations.keyAt(i);
annotation = mAnnotations.get(ids[i]);
if (annotation instanceof Marker) {
((Marker) annotation).hideInfoWindow();
removeMarkerView(annotation.getId());
Marker marker = (Marker) annotation;
marker.hideInfoWindow();
removeMarkerView(marker);
mMarkerViewMap.remove(marker);
}
}
mMapView.removeAnnotations(ids);
@@ -1251,11 +1279,14 @@ public class MapboxMap {
marker.hideInfoWindow();
}
View viewMarker = mMarkerViews.get(marker.getId());
View viewMarker = mMarkerViewMap.get(marker);
if (viewMarker != null) {
Animator animator = AnimatorInflater.loadAnimator(mMapView.getContext(), mMarkerViewItemAnimatorOutRes);
animator.setTarget(viewMarker);
animator.start();
int deselectAnimatorRes = mMarkerViewSettingsMap.get(marker.getId()).getAnimDeselectRes();
if (deselectAnimatorRes != 0) {
Animator animator = AnimatorInflater.loadAnimator(mMapView.getContext(), deselectAnimatorRes);
animator.setTarget(viewMarker);
animator.start();
}
}
}
@@ -1291,8 +1322,13 @@ public class MapboxMap {
private Marker prepareMarker(BaseMarkerOptions markerOptions) {
Marker marker = markerOptions.getMarker();
Icon icon = mMapView.loadIconForMarker(marker);
marker.setTopOffsetPixels(mMapView.getTopOffsetPixelsForIcon(icon));
if (markerOptions.isViewMarker()) {
Icon icon = IconFactory.recreate("markerViewSettings", mViewMarkerBitmap);
marker.setIcon(icon);
} else {
Icon icon = mMapView.loadIconForMarker(marker);
marker.setTopOffsetPixels(mMapView.getTopOffsetPixelsForIcon(icon));
}
return marker;
}
@@ -1311,25 +1347,6 @@ public class MapboxMap {
mOnMarkerViewClickListener = listener;
}
public OnMarkerViewClickListener getOnMarkerViewClickListener() {
return mOnMarkerViewClickListener;
}
public void setMarkerViewItemAnimation(@AnimatorRes int animationInRes, @AnimatorRes int animationOutRes) {
mMarkerViewItemAnimatorInRes = animationInRes;
mMarkerViewItemAnimatorOutRes = animationOutRes;
}
@AnimatorRes
public int getMarkerViewItemAnimatorInRes() {
return mMarkerViewItemAnimatorInRes;
}
@AnimatorRes
public int getMarkerViewItemAnimatorOutRes() {
return mMarkerViewItemAnimatorOutRes;
}
//
// InfoWindow
//
@@ -1385,9 +1402,8 @@ public class MapboxMap {
return mInfoWindows;
}
// used by MapView
LongSparseArray<View> getMarkerViews() {
return mMarkerViews;
Map<Marker, View> getMarkerViewMap() {
return mMarkerViewMap;
}
private boolean isInfoWindowValidForMarker(@NonNull Marker marker) {
@@ -1920,17 +1936,19 @@ public class MapboxMap {
public static abstract class MarkerViewAdapter<U extends Marker> {
private Context context;
private final Class<U> persistentClass;
private final Pools.SimplePool<View> mViewReusePool;
@SuppressWarnings("unchecked")
public MarkerViewAdapter(Context context) {
this.context = context;
persistentClass = (Class<U>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
mViewReusePool = new Pools.SimplePool<>(20);
}
@Nullable
public abstract View getView(@NonNull U marker, @Nullable View convertView, @NonNull ViewGroup parent);
public abstract View getView(@NonNull U marker, @NonNull View convertView, @NonNull ViewGroup parent);
public Class<U> getMarkerClass() {
return persistentClass;
@@ -1939,6 +1957,15 @@ public class MapboxMap {
public Pools.SimplePool<View> getViewReusePool() {
return mViewReusePool;
}
public Context getContext() {
return context;
}
public MarkerViewSettings getMarkerViewSettings(Marker marker) {
return new MarkerViewSettings.Builder().build();
}
}
public interface OnMarkerViewClickListener {