[android] - add OnMarkerView add callback (#7429)

This commit is contained in:
Tobrun
2016-12-14 22:09:30 +01:00
committed by GitHub
parent f74de67315
commit 05c6935556
6 changed files with 182 additions and 70 deletions

View File

@@ -6,6 +6,7 @@ import android.graphics.RectF;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.LongSparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -13,6 +14,7 @@ import android.widget.ImageView;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.utils.AnimatorUtils;
@@ -28,10 +30,11 @@ import java.util.Map;
* This class is responsible for managing a {@link MarkerView} item.
* </p>
*/
public class MarkerViewManager {
public class MarkerViewManager implements MapView.OnMapChangedListener {
private final ViewGroup markerViewContainer;
private final Map<MarkerView, View> markerViewMap = new HashMap<>();
private final LongSparseArray<OnMarkerViewAddedListener> markerViewAddedListenerMap = new LongSparseArray<>();
private final List<MapboxMap.MarkerViewAdapter> markerViewAdapters = new ArrayList<>();
// TODO refactor MapboxMap out for Projection and Transform
@@ -40,6 +43,7 @@ public class MarkerViewManager {
private long viewMarkerBoundsUpdateTime;
private MapboxMap.OnMarkerViewClickListener onMarkerViewClickListener;
private boolean isWaitingForRenderInvoke;
/**
* Creates an instance of MarkerViewManager.
@@ -57,6 +61,19 @@ public class MarkerViewManager {
this.mapboxMap = mapboxMap;
}
@Override
public void onMapChanged(@MapView.MapChange int change) {
if (isWaitingForRenderInvoke && change == MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) {
isWaitingForRenderInvoke = false;
invalidateViewMarkersInVisibleRegion();
}
}
public void setWaitingForRenderInvoke(boolean waitingForRenderInvoke) {
isWaitingForRenderInvoke = waitingForRenderInvoke;
}
/**
* Animate a MarkerView to a given rotation.
* <p>
@@ -470,10 +487,21 @@ public class MarkerViewManager {
markerViewContainer.addView(adaptedView);
}
}
// notify listener is marker view is rendered
OnMarkerViewAddedListener onViewAddedListener = markerViewAddedListenerMap.get(marker.getId());
if (onViewAddedListener != null) {
onViewAddedListener.onViewAdded(marker);
markerViewAddedListenerMap.remove(marker.getId());
}
}
}
}
}
// clear map, don't keep references to MarkerView listeners that are not found in the bounds of the map.
markerViewAddedListenerMap.clear();
// trigger update to make newly added ViewMarker visible,
// these would only be updated when the map is moved.
update();
@@ -555,6 +583,10 @@ public class MarkerViewManager {
return markerViewContainer;
}
public void addOnMarkerViewAddedListener(MarkerView markerView, OnMarkerViewAddedListener onMarkerViewAddedListener) {
markerViewAddedListenerMap.put(markerView.getId(), onMarkerViewAddedListener);
}
/**
* Default MarkerViewAdapter used for base class of {@link MarkerView} to adapt a MarkerView to
* an ImageView.
@@ -588,4 +620,21 @@ public class MarkerViewManager {
ImageView imageView;
}
}
/**
* Interface definition invoked when the View of a MarkerView has been added to the map.
* <p>
* {@link MapboxMap#addMarker(BaseMarkerOptions)}
* and only when the related MarkerView is found in the viewport of the map.
* </p>
*/
public interface OnMarkerViewAddedListener {
/**
* Invoked when the View of a MarkerView has been added to the Map.
*
* @param markerView The MarkerView the View was added for
*/
void onViewAdded(@NonNull MarkerView markerView);
}
}

View File

@@ -20,6 +20,7 @@ import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
@@ -32,7 +33,7 @@ import java.util.List;
* Exposes convenience methods to add/remove/update all subtypes of annotations found in com.mapbox.mapboxsdk.annotations.
* </p>
*/
class AnnotationManager implements MapView.OnMapChangedListener {
class AnnotationManager {
private final NativeMapView nativeMapView;
private final MapView mapView;
@@ -44,8 +45,8 @@ class AnnotationManager implements MapView.OnMapChangedListener {
private MapboxMap mapboxMap;
private HashMap<MarkerView, MarkerViewManager.OnMarkerViewAddedListener> markerMap = new HashMap<>();
private MapboxMap.OnMarkerClickListener onMarkerClickListener;
private boolean isWaitingForRenderInvoke;
AnnotationManager(NativeMapView view, MapView mapView, MarkerViewManager markerViewManager) {
this.nativeMapView = view;
@@ -54,7 +55,7 @@ class AnnotationManager implements MapView.OnMapChangedListener {
this.markerViewManager = markerViewManager;
if (view != null) {
// null checking needed for unit tests
view.addOnMapChangedListener(this);
nativeMapView.addOnMapChangedListener(markerViewManager);
}
}
@@ -66,14 +67,6 @@ class AnnotationManager implements MapView.OnMapChangedListener {
return this;
}
@Override
public void onMapChanged(@MapView.MapChange int change) {
if (isWaitingForRenderInvoke && change == MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) {
isWaitingForRenderInvoke = false;
markerViewManager.invalidateViewMarkersInVisibleRegion();
}
}
//
// Annotations
//
@@ -218,7 +211,6 @@ class AnnotationManager implements MapView.OnMapChangedListener {
}
MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions, @NonNull MapboxMap mapboxMap) {
isWaitingForRenderInvoke = true;
MarkerView marker = prepareViewMarker(markerOptions);
marker.setMapboxMap(mapboxMap);
long id = nativeMapView.addMarker(marker);
@@ -227,13 +219,28 @@ class AnnotationManager implements MapView.OnMapChangedListener {
return marker;
}
public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions, @NonNull MapboxMap mapboxMap, final MarkerViewManager.OnMarkerViewAddedListener onMarkerViewAddedListener) {
final MarkerView marker = prepareViewMarker(markerOptions);
// add marker to map
marker.setMapboxMap(mapboxMap);
long id = nativeMapView.addMarker(marker);
marker.setId(id);
annotations.put(id, marker);
markerViewManager.addOnMarkerViewAddedListener(marker, onMarkerViewAddedListener);
markerViewManager.setWaitingForRenderInvoke(true);
return marker;
}
List<MarkerView> addMarkerViews(@NonNull List<? extends BaseMarkerViewOptions> markerViewOptions, @NonNull MapboxMap mapboxMap) {
List<MarkerView> markers = new ArrayList<>();
for (BaseMarkerViewOptions markerViewOption : markerViewOptions) {
// if last marker
if (markerViewOptions.indexOf(markerViewOption) == markerViewOptions.size() - 1) {
// get notified when render occurs to invalidate and draw MarkerViews
isWaitingForRenderInvoke = true;
markerViewManager.setWaitingForRenderInvoke(true);
}
// add marker to map
MarkerView marker = prepareViewMarker(markerViewOption);

View File

@@ -905,7 +905,25 @@ public final class MapboxMap {
@UiThread
@NonNull
public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions) {
return annotationManager.addMarker(markerOptions, this);
return annotationManager.addMarker(markerOptions, this, null);
}
/**
* <p>
* Adds a marker to this map.
* </p>
* The marker's icon is rendered on the map at the location {@code Marker.position}.
* If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
*
* @param markerOptions A marker options object that defines how to render the marker.
* @param onMarkerViewAddedListener Callback invoked when the View has been added to the map.
* @return The {@code Marker} that was added to the map.
*/
@UiThread
@NonNull
public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions, final MarkerViewManager.OnMarkerViewAddedListener onMarkerViewAddedListener) {
return annotationManager.addMarker(markerOptions, this, onMarkerViewAddedListener);
}
@UiThread