[android] Update marker position and icon #3885

This commit is contained in:
Gabriel Miklós
2016-02-14 22:04:54 +01:00
committed by Tobrun
parent 97ff6cfd49
commit b395302990
5 changed files with 153 additions and 21 deletions

View File

@@ -61,8 +61,17 @@ public final class Marker extends Annotation {
return infoWindowShown;
}
void setPosition(LatLng position) {
/**
* Sets the position.
*
* @param position new position
*/
public void setPosition(LatLng position) {
this.position = position;
MapboxMap map = getMapboxMap();
if (map != null) {
map.updateMarker(this);
}
}
void setSnippet(String snippet) {
@@ -70,10 +79,16 @@ public final class Marker extends Annotation {
}
/**
* Do not use this method. Used internally by the SDK.
* Sets the icon.
*
* @param icon The icon to be used as Marker image
*/
public void setIcon(@Nullable Icon icon) {
this.icon = icon;
MapboxMap map = getMapboxMap();
if (map != null) {
map.updateMarker(this);
}
}
public Icon getIcon() {

View File

@@ -31,6 +31,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresPermission;
import android.support.annotation.UiThread;
import android.support.v4.util.LongSparseArray;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.ScaleGestureDetectorCompat;
import android.support.v7.app.AlertDialog;
@@ -90,6 +91,10 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* <p>
@@ -116,7 +121,7 @@ public class MapView extends FrameLayout {
private static final float DIMENSION_SEVENTYSIX_DP = 76f;
private MapboxMap mMapboxMap;
private List<Annotation> mAnnotations;
private LongSparseArray<Annotation> mAnnotations;
private List<Icon> mIcons;
private NativeMapView mNativeMapView;
@@ -167,7 +172,7 @@ public class MapView extends FrameLayout {
private void initialize(@NonNull Context context, @Nullable AttributeSet attrs) {
mOnMapChangedListener = new CopyOnWriteArrayList<>();
mMapboxMap = new MapboxMap(this);
mAnnotations = new ArrayList<>();
mAnnotations = new LongSparseArray<>();
mIcons = new ArrayList<>();
View view = LayoutInflater.from(context).inflate(R.layout.mapview_internal, this);
@@ -1007,6 +1012,11 @@ public class MapView extends FrameLayout {
private Marker prepareMarker(MarkerOptions markerOptions) {
Marker marker = markerOptions.getMarker();
ensureIconLoaded(marker);
return marker;
}
private void ensureIconLoaded(Marker marker) {
Icon icon = marker.getIcon();
if (icon == null) {
icon = IconFactory.getInstance(getContext()).defaultMarker();
@@ -1021,8 +1031,12 @@ public class MapView extends FrameLayout {
throw new IconBitmapChangedException();
}
}
marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
return marker;
// this seems to be a costly operation according to the profiler so I'm trying to save some calls
Marker previousMarker = marker.getId() != -1 ? (Marker) mAnnotations.get(marker.getId()) : null;
if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) {
marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
}
}
/**
@@ -1047,10 +1061,38 @@ public class MapView extends FrameLayout {
long id = mNativeMapView.addMarker(marker);
marker.setId(id); // the annotation needs to know its id
marker.setMapboxMap(mMapboxMap); // the annotation needs to know which map view it is in
mAnnotations.add(marker);
mAnnotations.put(id, marker);
return marker;
}
/**
* <p>
* Updates a marker on this map. Does nothing if the marker is already added.
* </p>
*
* @param updatedMarker An updated marker object.
*/
@UiThread
void updateMarker(@NonNull Marker updatedMarker) {
if (updatedMarker == null) {
Log.w(TAG, "marker was null, doing nothing");
return;
}
if (updatedMarker.getId() == -1) {
Log.w(TAG, "marker has an id of -1, possibly was not added yet, doing nothing");
}
ensureIconLoaded(updatedMarker);
mNativeMapView.updateMarker(updatedMarker);
int index = mAnnotations.indexOfKey(updatedMarker.getId());
if (index > -1) {
mAnnotations.setValueAt(index, updatedMarker);
}
}
/**
* <p>
* Adds multiple markers to this map.
@@ -1084,7 +1126,7 @@ public class MapView extends FrameLayout {
m = markers.get(i);
m.setId(ids[i]);
m.setMapboxMap(mMapboxMap);
mAnnotations.add(m);
mAnnotations.put(ids[i], m);
}
return new ArrayList<>(markers);
@@ -1108,7 +1150,7 @@ public class MapView extends FrameLayout {
long id = mNativeMapView.addPolyline(polyline);
polyline.setId(id);
polyline.setMapboxMap(mMapboxMap);
mAnnotations.add(polyline);
mAnnotations.put(id, polyline);
return polyline;
}
@@ -1139,7 +1181,7 @@ public class MapView extends FrameLayout {
p = polylines.get(i);
p.setId(ids[i]);
p.setMapboxMap(mMapboxMap);
mAnnotations.add(p);
mAnnotations.put(ids[i], p);
}
return new ArrayList<>(polylines);
@@ -1163,7 +1205,7 @@ public class MapView extends FrameLayout {
long id = mNativeMapView.addPolygon(polygon);
polygon.setId(id);
polygon.setMapboxMap(mMapboxMap);
mAnnotations.add(polygon);
mAnnotations.put(id, polygon);
return polygon;
}
@@ -1195,7 +1237,7 @@ public class MapView extends FrameLayout {
p = polygons.get(i);
p.setId(ids[i]);
p.setMapboxMap(mMapboxMap);
mAnnotations.add(p);
mAnnotations.put(ids[i], p);
}
return new ArrayList<>(polygons);
@@ -1232,7 +1274,7 @@ public class MapView extends FrameLayout {
}
long id = annotation.getId();
mNativeMapView.removeAnnotation(id);
mAnnotations.remove(annotation);
mAnnotations.delete(id);
}
/**
@@ -1261,10 +1303,10 @@ public class MapView extends FrameLayout {
@UiThread
void removeAllAnnotations() {
int count = mAnnotations.size();
long[] ids = new long[mAnnotations.size()];
long[] ids = new long[count];
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.get(i);
Annotation annotation = mAnnotations.valueAt(i);
long id = annotation.getId();
ids[i] = id;
if (annotation instanceof Marker) {
@@ -1283,8 +1325,14 @@ public class MapView extends FrameLayout {
* list will not update the map.
*/
@NonNull
List<Annotation> getAllAnnotations() {
return new ArrayList<>(mAnnotations);
public List<Annotation> getAllAnnotations() {
List<Annotation> copyOfAnnotations = new ArrayList<>(mAnnotations.size());
for (int i = 0; i < mAnnotations.size(); i++) {
copyOfAnnotations.add(mAnnotations.valueAt(i));
}
return copyOfAnnotations;
}
private List<Marker> getMarkersInBounds(@NonNull LatLngBounds bbox) {
@@ -1304,7 +1352,7 @@ public class MapView extends FrameLayout {
List<Marker> annotations = new ArrayList<>(ids.length);
int count = mAnnotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.get(i);
Annotation annotation = mAnnotations.valueAt(i);
if (annotation instanceof Marker && idsList.contains(annotation.getId())) {
annotations.add((Marker) annotation);
}
@@ -1435,7 +1483,7 @@ public class MapView extends FrameLayout {
private void adjustTopOffsetPixels() {
int count = mAnnotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.get(i);
Annotation annotation = mAnnotations.valueAt(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
marker.setTopOffsetPixels(
@@ -1454,7 +1502,7 @@ public class MapView extends FrameLayout {
private void reloadMarkers() {
int count = mAnnotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.get(i);
Annotation annotation = mAnnotations.valueAt(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
mNativeMapView.removeAnnotation(annotation.getId());
@@ -1760,7 +1808,7 @@ public class MapView extends FrameLayout {
if (newSelectedMarkerId >= 0) {
int count = mAnnotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.get(i);
Annotation annotation = mAnnotations.valueAt(i);
if (annotation instanceof Marker) {
if (annotation.getId() == newSelectedMarkerId) {
if (selectedMarkers.isEmpty() || !selectedMarkers.contains(annotation)) {

View File

@@ -536,6 +536,18 @@ public class MapboxMap {
return mMapView.addMarkers(markerOptionsList);
}
/**
* <p>
* Updates a marker on this map. Does nothing if the marker is already added.
* </p>
*
* @param updatedMarker An updated marker object.
*/
@UiThread
public void updateMarker(@NonNull Marker updatedMarker) {
mMapView.updateMarker(updatedMarker);
}
/**
* Adds a polyline to this map.
*

View File

@@ -395,6 +395,10 @@ final class NativeMapView {
return nativeAddPolygons(mNativeMapViewPtr, polygon);
}
public void updateMarker(Marker marker) {
nativeUpdateMarker(mNativeMapViewPtr, marker);
}
public void removeAnnotation(long id) {
nativeRemoveAnnotation(mNativeMapViewPtr, id);
}
@@ -619,6 +623,8 @@ final class NativeMapView {
private native long nativeAddMarker(long nativeMapViewPtr, Marker marker);
private native void nativeUpdateMarker(long nativeMapViewPtr, Marker marker);
private native long[] nativeAddMarkers(long nativeMapViewPtr, List<Marker> markers);
private native long nativeAddPolyline(long nativeMapViewPtr, Polyline polyline);