Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions plugin-annotation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Mapbox welcomes participation and contributions from everyone.

### mapbox-android-plugin-annotation-v9:0.9.0 - XXX
#### Bugs
- Consumable events for click listeners [1124](https://github.com/mapbox/mapbox-plugins-android/pull/1124)
- Support multiple manager to be draggable [1125](https://github.com/mapbox/mapbox-plugins-android/pull/1125)
- End of drag event is consumed [1141](https://github.com/mapbox/mapbox-plugins-android/pull/1141)

### mapbox-android-plugin-annotation-v9:0.8.0 - March 5, 2020
#### Features
- Switching all plugins to AndroidX [#1100](https://github.com/mapbox/mapbox-plugins-android/pull/1100)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ public abstract class AnnotationManager<
final Map<String, PropertyValue> constantPropertyUsageMap = new HashMap<>();
Expression layerFilter;

private final DraggableAnnotationController<T, D> draggableAnnotationController;
private final List<D> dragListeners = new ArrayList<>();
private final List<U> clickListeners = new ArrayList<>();
private final List<V> longClickListeners = new ArrayList<>();
Expand All @@ -63,25 +62,26 @@ public abstract class AnnotationManager<
private Style style;
private String belowLayerId;
private CoreElementProvider<L> coreElementProvider;
private DraggableAnnotationController draggableAnnotationController;

@UiThread
protected AnnotationManager(MapView mapView, final MapboxMap mapboxMap, Style style,
CoreElementProvider<L> coreElementProvider,
DraggableAnnotationController<T, D> draggableAnnotationController,
DraggableAnnotationController draggableAnnotationController,
String belowLayerId, final GeoJsonOptions geoJsonOptions) {
this.mapboxMap = mapboxMap;
this.style = style;
this.belowLayerId = belowLayerId;
this.coreElementProvider = coreElementProvider;
this.draggableAnnotationController = draggableAnnotationController;

if (!style.isFullyLoaded()) {
throw new RuntimeException("The style has to be non-null and fully loaded.");
}

mapboxMap.addOnMapClickListener(mapClickResolver = new MapClickResolver());
mapboxMap.addOnMapLongClickListener(mapClickResolver);
this.draggableAnnotationController = draggableAnnotationController;
draggableAnnotationController.injectAnnotationManager(this);
draggableAnnotationController.addAnnotationManager(this);

initializeSourcesAndLayers(geoJsonOptions);

Expand Down Expand Up @@ -332,6 +332,7 @@ List<D> getDragListeners() {
public void onDestroy() {
mapboxMap.removeOnMapClickListener(mapClickResolver);
mapboxMap.removeOnMapLongClickListener(mapClickResolver);
draggableAnnotationController.removeAnnotationManager(this);
dragListeners.clear();
clickListeners.clear();
longClickListeners.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ public CircleManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @No
*/
@UiThread
public CircleManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions) {
this(mapView, mapboxMap, style, new CircleElementProvider(), belowLayerId, geoJsonOptions, new DraggableAnnotationController<Circle, OnCircleDragListener>(mapView, mapboxMap));
this(mapView, mapboxMap, style, new CircleElementProvider(), belowLayerId, geoJsonOptions, DraggableAnnotationController.getInstance(mapView, mapboxMap));
}

@VisibleForTesting
CircleManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @NonNull CoreElementProvider<CircleLayer> coreElementProvider, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions, DraggableAnnotationController<Circle, OnCircleDragListener> draggableAnnotationController) {
CircleManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @NonNull CoreElementProvider<CircleLayer> coreElementProvider, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions, DraggableAnnotationController draggableAnnotationController) {
super(mapView, mapboxMap, style, coreElementProvider, draggableAnnotationController, belowLayerId, geoJsonOptions);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,42 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

final class DraggableAnnotationController<T extends Annotation, D extends OnAnnotationDragListener<T>> {
import java.util.ArrayList;
import java.util.List;

final class DraggableAnnotationController {

private static DraggableAnnotationController INSTANCE = null;
private static MapView MAP_VIEW = null;
private static MapboxMap MAPBOX_MAP = null;

public static synchronized DraggableAnnotationController getInstance(MapView mapView, MapboxMap mapboxMap) {
if(INSTANCE == null || MAP_VIEW != mapView || MAPBOX_MAP != mapboxMap) {
MAPBOX_MAP = mapboxMap;
MAP_VIEW = mapView;
INSTANCE = new DraggableAnnotationController(MAP_VIEW, MAPBOX_MAP);
}
return INSTANCE;
}

private static synchronized void clearInstance() {
INSTANCE = null;
MAP_VIEW = null;
MAPBOX_MAP = null;
}

private final MapboxMap mapboxMap;
private AnnotationManager<?, T, ?, D, ?, ?> annotationManager;
private List<AnnotationManager> annotationManagers = new ArrayList<>();

private final int touchAreaShiftX;
private final int touchAreaShiftY;
private final int touchAreaMaxX;
private final int touchAreaMaxY;

@Nullable
private T draggedAnnotation;
private Annotation draggedAnnotation;
@Nullable
private AnnotationManager draggedAnnotationManager;

@SuppressLint("ClickableViewAccessibility")
DraggableAnnotationController(MapView mapView, MapboxMap mapboxMap) {
Expand All @@ -50,27 +75,37 @@ public DraggableAnnotationController(MapView mapView, MapboxMap mapboxMap,
mapView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// Using active gesture manager
Annotation oldAnnotation = draggedAnnotation;
androidGesturesManager.onTouchEvent(event);
// if drag is started or drag is finished, don't pass motion events further
return draggedAnnotation != null || oldAnnotation != draggedAnnotation;
return draggedAnnotation != null || oldAnnotation != null;
}
});
}

void injectAnnotationManager(AnnotationManager<?, T, ?, D, ?, ?> annotationManager) {
this.annotationManager = annotationManager;
synchronized void addAnnotationManager(AnnotationManager annotationManager) {
this.annotationManagers.add(annotationManager);
}

synchronized void removeAnnotationManager(AnnotationManager annotationManager) {
this.annotationManagers.remove(annotationManager);
if(annotationManagers.isEmpty()) {
clearInstance();
}
}

void onSourceUpdated() {
stopDragging(draggedAnnotation);
stopDragging(draggedAnnotation, draggedAnnotationManager);
}

boolean onMoveBegin(MoveGestureDetector detector) {
if (detector.getPointersCount() == 1) {
T annotation = annotationManager.queryMapForFeatures(detector.getFocalPoint());
if (annotation != null) {
return startDragging(annotation);
for (AnnotationManager annotationManager : annotationManagers) {
if (detector.getPointersCount() == 1) {
Annotation annotation = annotationManager.queryMapForFeatures(detector.getFocalPoint());
if (annotation != null && startDragging(annotation, annotationManager)) {
return true;
}
}
}
return false;
Expand All @@ -79,7 +114,7 @@ boolean onMoveBegin(MoveGestureDetector detector) {
boolean onMove(MoveGestureDetector detector) {
if (draggedAnnotation != null && (detector.getPointersCount() > 1 || !draggedAnnotation.isDraggable())) {
// Stopping the drag when we don't work with a simple, on-pointer move anymore
stopDragging(draggedAnnotation);
stopDragging(draggedAnnotation, draggedAnnotationManager);
return true;
}

Expand All @@ -93,7 +128,7 @@ boolean onMove(MoveGestureDetector detector) {
PointF pointF = new PointF(x, y);

if (pointF.x < 0 || pointF.y < 0 || pointF.x > touchAreaMaxX || pointF.y > touchAreaMaxY) {
stopDragging(draggedAnnotation);
stopDragging(draggedAnnotation, draggedAnnotationManager);
return true;
}

Expand All @@ -105,11 +140,9 @@ boolean onMove(MoveGestureDetector detector) {
draggedAnnotation.setGeometry(
shiftedGeometry
);
annotationManager.internalUpdateSource();
if (!annotationManager.getDragListeners().isEmpty()) {
for (D d : annotationManager.getDragListeners()) {
d.onAnnotationDrag(draggedAnnotation);
}
draggedAnnotationManager.internalUpdateSource();
for (OnAnnotationDragListener d : (List<OnAnnotationDragListener>)draggedAnnotationManager.getDragListeners()) {
d.onAnnotationDrag(draggedAnnotation);
}
return true;
}
Expand All @@ -120,31 +153,29 @@ boolean onMove(MoveGestureDetector detector) {

void onMoveEnd() {
// Stopping the drag when move ends
stopDragging(draggedAnnotation);
stopDragging(draggedAnnotation, draggedAnnotationManager);
}

boolean startDragging(@NonNull T annotation) {
boolean startDragging(@NonNull Annotation annotation, @NonNull AnnotationManager annotationManager) {
if (annotation.isDraggable()) {
if (!annotationManager.getDragListeners().isEmpty()) {
for (D d : annotationManager.getDragListeners()) {
d.onAnnotationDragStarted(annotation);
}
for (OnAnnotationDragListener d : (List<OnAnnotationDragListener>)annotationManager.getDragListeners()) {
d.onAnnotationDragStarted(annotation);
}
draggedAnnotation = annotation;
draggedAnnotationManager = annotationManager;
return true;
}
return false;
}

void stopDragging(@Nullable T annotation) {
if (annotation != null) {
if (!annotationManager.getDragListeners().isEmpty()) {
for (D d : annotationManager.getDragListeners()) {
d.onAnnotationDragFinished(annotation);
}
void stopDragging(@Nullable Annotation annotation, @Nullable AnnotationManager annotationManager) {
if (annotation != null && annotationManager != null) {
for (OnAnnotationDragListener d : (List<OnAnnotationDragListener>)annotationManager.getDragListeners()) {
d.onAnnotationDragFinished(annotation);
}
}
draggedAnnotation = null;
draggedAnnotationManager = null;
}

private class AnnotationMoveGestureListener implements MoveGestureDetector.OnMoveGestureListener {
Expand All @@ -164,4 +195,4 @@ public void onMoveEnd(MoveGestureDetector detector, float velocityX, float veloc
DraggableAnnotationController.this.onMoveEnd();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ public FillManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonN
*/
@UiThread
public FillManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions) {
this(mapView, mapboxMap, style, new FillElementProvider(), belowLayerId, geoJsonOptions, new DraggableAnnotationController<Fill, OnFillDragListener>(mapView, mapboxMap));
this(mapView, mapboxMap, style, new FillElementProvider(), belowLayerId, geoJsonOptions, DraggableAnnotationController.getInstance(mapView, mapboxMap));
}

@VisibleForTesting
FillManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @NonNull CoreElementProvider<FillLayer> coreElementProvider, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions, DraggableAnnotationController<Fill, OnFillDragListener> draggableAnnotationController) {
FillManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @NonNull CoreElementProvider<FillLayer> coreElementProvider, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions, DraggableAnnotationController draggableAnnotationController) {
super(mapView, mapboxMap, style, coreElementProvider, draggableAnnotationController, belowLayerId, geoJsonOptions);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ public LineManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonN
*/
@UiThread
public LineManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions) {
this(mapView, mapboxMap, style, new LineElementProvider(), belowLayerId, geoJsonOptions, new DraggableAnnotationController<Line, OnLineDragListener>(mapView, mapboxMap));
this(mapView, mapboxMap, style, new LineElementProvider(), belowLayerId, geoJsonOptions, DraggableAnnotationController.getInstance(mapView, mapboxMap));
}

@VisibleForTesting
LineManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @NonNull CoreElementProvider<LineLayer> coreElementProvider, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions, DraggableAnnotationController<Line, OnLineDragListener> draggableAnnotationController) {
LineManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @NonNull CoreElementProvider<LineLayer> coreElementProvider, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions, DraggableAnnotationController draggableAnnotationController) {
super(mapView, mapboxMap, style, coreElementProvider, draggableAnnotationController, belowLayerId, geoJsonOptions);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ public SymbolManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @No
*/
@UiThread
public SymbolManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions) {
this(mapView, mapboxMap, style, new SymbolElementProvider(), belowLayerId, geoJsonOptions, new DraggableAnnotationController<Symbol, OnSymbolDragListener>(mapView, mapboxMap));
this(mapView, mapboxMap, style, new SymbolElementProvider(), belowLayerId, geoJsonOptions, DraggableAnnotationController.getInstance(mapView, mapboxMap));
}

@VisibleForTesting
SymbolManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @NonNull CoreElementProvider<SymbolLayer> coreElementProvider, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions, DraggableAnnotationController<Symbol, OnSymbolDragListener> draggableAnnotationController) {
SymbolManager(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @NonNull Style style, @NonNull CoreElementProvider<SymbolLayer> coreElementProvider, @Nullable String belowLayerId, @Nullable GeoJsonOptions geoJsonOptions, DraggableAnnotationController draggableAnnotationController) {
super(mapView, mapboxMap, style, coreElementProvider, draggableAnnotationController, belowLayerId, geoJsonOptions);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

public class CircleManagerTest {

private DraggableAnnotationController<Circle, OnCircleDragListener> draggableAnnotationController = mock(DraggableAnnotationController.class);
private DraggableAnnotationController draggableAnnotationController = mock(DraggableAnnotationController.class);
private MapView mapView = mock(MapView.class);
private MapboxMap mapboxMap = mock(MapboxMap.class);
private Style style = mock(Style.class);
Expand Down
Loading