From 927b4c6dbe6c81aa4df0f662044ec3c9e55a8458 Mon Sep 17 00:00:00 2001 From: Leith Bade Date: Thu, 8 Oct 2015 13:22:28 +1100 Subject: [PATCH] [android] Refactor annotations API Remove unimplemented properties. Correct defintions of equals() and hasCode(). Add setOnInfoWindowClickListener and remove old method from Marker. Refactor showInfoWindow() to remove need for exposing internal method. Make select/deselectMarker public. Add getSelectedMarker. Fix bug where you couldn't reselect a closed info window. Add empty constructor to LatLng and LatLngZoom. Fixes #2546 Fixes #2631 Fixes #2448 --- android/cpp/jni.cpp | 39 ----- .../mapboxsdk/annotations/Annotation.java | 72 +++----- .../mapbox/mapboxsdk/annotations/Circle.java | 67 -------- .../mapboxsdk/annotations/CircleOptions.java | 81 --------- .../mapboxsdk/annotations/InfoWindow.java | 95 ++++------- .../mapboxsdk/annotations/InfoWindowView.java | 8 +- .../mapbox/mapboxsdk/annotations/Marker.java | 154 ++++-------------- .../mapboxsdk/annotations/MarkerOptions.java | 106 +++--------- .../mapboxsdk/annotations/MultiPoint.java | 24 +-- .../mapbox/mapboxsdk/annotations/Polygon.java | 68 -------- .../mapboxsdk/annotations/PolygonOptions.java | 86 +++------- .../mapboxsdk/annotations/Polyline.java | 7 - .../annotations/PolylineOptions.java | 34 ++-- .../mapboxsdk/annotations/SpriteFactory.java | 7 +- .../com/mapbox/mapboxsdk/geometry/LatLng.java | 8 + .../mapbox/mapboxsdk/geometry/LatLngZoom.java | 5 + .../com/mapbox/mapboxsdk/views/MapView.java | 135 +++++++++++---- .../mapboxsdk/views/UserLocationView.java | 2 +- .../mapboxsdk/testapp/MainActivity.java | 24 ++- include/mbgl/android/jni.hpp | 4 - 20 files changed, 298 insertions(+), 728 deletions(-) delete mode 100644 android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Circle.java delete mode 100644 android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/CircleOptions.java diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp index c242f94e380..94de069215c 100644 --- a/android/cpp/jni.cpp +++ b/android/cpp/jni.cpp @@ -66,19 +66,15 @@ jfieldID markerIconId = nullptr; jclass polylineClass = nullptr; jfieldID polylineAlphaId = nullptr; -jfieldID polylineVisibleId = nullptr; jfieldID polylineColorId = nullptr; jfieldID polylineWidthId = nullptr; jfieldID polylinePointsId = nullptr; jclass polygonClass = nullptr; jfieldID polygonAlphaId = nullptr; -jfieldID polygonVisibleId = nullptr; jfieldID polygonFillColorId = nullptr; jfieldID polygonStrokeColorId = nullptr; -jfieldID polygonStrokeWidthId = nullptr; jfieldID polygonPointsId = nullptr; -jfieldID polygonHolesId = nullptr; jclass runtimeExceptionClass = nullptr; jclass nullPointerExceptionClass = nullptr; @@ -338,7 +334,6 @@ mbgl::AnnotationSegment annotation_segment_from_latlng_jlist(JNIEnv *env, jobjec std::pair annotation_std_pair_from_polygon_jobject(JNIEnv *env, jobject polygon) { jfloat alpha = env->GetFloatField(polygon, polygonAlphaId); - //jboolean visible = env->GetBooleanField(polygon, polygonVisibleId); jint fillColor = env->GetIntField(polygon, polygonFillColorId); jint strokeColor = env->GetIntField(polygon, polygonStrokeColorId); @@ -918,12 +913,6 @@ jlong JNICALL nativeAddPolyline(JNIEnv *env, jobject obj, jlong nativeMapViewPtr return -1; } - /*jboolean visible = env->GetBooleanField(polyline, polylineVisibleId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - }*/ - jint color = env->GetIntField(polyline, polylineColorId); if (env->ExceptionCheck()) { env->ExceptionDescribe(); @@ -1476,12 +1465,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } - polylineVisibleId = env->GetFieldID(polylineClass, "visible", "Z"); - if (polylineVisibleId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - polylineColorId = env->GetFieldID(polylineClass, "color", "I"); if (polylineColorId == nullptr) { env->ExceptionDescribe(); @@ -1512,12 +1495,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } - polygonVisibleId = env->GetFieldID(polygonClass, "visible", "Z"); - if (polygonVisibleId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - polygonFillColorId = env->GetFieldID(polygonClass, "fillColor", "I"); if (polygonFillColorId == nullptr) { env->ExceptionDescribe(); @@ -1530,24 +1507,12 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } - polygonStrokeWidthId = env->GetFieldID(polygonClass, "strokeWidth", "F"); - if (polygonStrokeWidthId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - polygonPointsId = env->GetFieldID(polygonClass, "points", "Ljava/util/List;"); if (polygonPointsId == nullptr) { env->ExceptionDescribe(); return JNI_ERR; } - polygonHolesId = env->GetFieldID(polygonClass, "holes", "Ljava/util/List;"); - if (polygonHolesId == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - jclass nativeMapViewClass = env->FindClass("com/mapbox/mapboxsdk/views/NativeMapView"); if (nativeMapViewClass == nullptr) { env->ExceptionDescribe(); @@ -2040,7 +2005,6 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { env->DeleteGlobalRef(polylineClass); polylineClass = nullptr; polylineAlphaId = nullptr; - polylineVisibleId = nullptr; polylineColorId = nullptr; polylineWidthId = nullptr; polylinePointsId = nullptr; @@ -2048,12 +2012,9 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { env->DeleteGlobalRef(polygonClass); polygonClass = nullptr; polygonAlphaId = nullptr; - polygonVisibleId = nullptr; polygonFillColorId = nullptr; polygonStrokeColorId = nullptr; - polygonStrokeWidthId = nullptr; polygonPointsId = nullptr; - polygonHolesId = nullptr; onInvalidateId = nullptr; onMapChangedId = nullptr; diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java index 1b8f6491ea8..ec733510b55 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java @@ -1,5 +1,7 @@ package com.mapbox.mapboxsdk.annotations; +import android.support.annotation.NonNull; + import com.mapbox.mapboxsdk.views.MapView; import java.lang.ref.WeakReference; @@ -8,19 +10,13 @@ public abstract class Annotation implements Comparable { /** * The annotation id - * + *

* Internal C++ id is stored as unsigned int. */ private long id = -1; // -1 unless added to a MapView private WeakReference mapView; - private float alpha = 1.0f; - private boolean visible = true; - - protected Annotation() {} - - public float getAlpha() { - return alpha; + protected Annotation() { } /** @@ -30,10 +26,6 @@ public long getId() { return id; } - boolean isVisible() { - return visible; - } - public void remove() { if ((mapView == null) || (mapView.get() == null)) { return; @@ -41,10 +33,6 @@ public void remove() { mapView.get().removeAnnotation(this); } - void setAlpha(float alpha) { - this.alpha = alpha; - } - /** * Do not use this method. Used internally by the SDK. */ @@ -56,7 +44,7 @@ public void setId(long id) { * Do not use this method. Used internally by the SDK. */ public void setMapView(MapView mapView) { - this.mapView = new WeakReference(mapView); + this.mapView = new WeakReference<>(mapView); } protected MapView getMapView() { @@ -66,41 +54,8 @@ protected MapView getMapView() { return mapView.get(); } - void setVisible(boolean visible) { - this.visible = visible; - } - - // TODO: Implement getZIndex of Google Maps Android API -// public float getZIndex() { -// -// } - - // TODO: Implement setZIndex of Google Maps Android API -// public void setZIndex(float zIndex) { -// -// } - - - @Override - public boolean equals(Object o) { - if (o == null) { - return false; - } - - if (o instanceof Annotation) { - Annotation comp = (Annotation) o; - return id == comp.id; - } - return false; - } - @Override - public int compareTo(Annotation annotation) { - - if (annotation == null) { - return -1; - } - + public int compareTo(@NonNull Annotation annotation) { if (id < annotation.getId()) { return 1; } else if (id > annotation.getId()) { @@ -110,4 +65,19 @@ public int compareTo(Annotation annotation) { // Equal return 0; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Annotation that = (Annotation) o; + + return getId() == that.getId(); + } + + @Override + public int hashCode() { + return (int) (getId() ^ (getId() >>> 32)); + } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Circle.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Circle.java deleted file mode 100644 index 4c994fbad83..00000000000 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Circle.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.mapbox.mapboxsdk.annotations; - - -import android.graphics.Color; - -import com.mapbox.mapboxsdk.geometry.LatLng; - -/** - * UNIMPLEMENTED: Needs implementation in Native. - * - * https://github.com/mapbox/mapbox-gl-native/issues/1882 - * https://github.com/mapbox/mapbox-gl-native/issues/1726 - */ -class Circle extends Annotation { - - private LatLng center; - private int fillColor = Color.BLACK; - private double radius; - private int strokeColor = Color.BLACK; - private float strokeWidth = 10; // Google Maps API defaults to 10 - - public LatLng getCenter() { - return center; - } - - public int getFillColor() { - return fillColor; - } - - /** - * Returns the circle's radius, in meters. - * - * @return radius in meters - */ - public double getRadius() { - return radius; - } - - public int getStrokeColor() { - return strokeColor; - } - - public float getStrokeWidth() { - return strokeWidth; - } - - void setCenter(LatLng center) { - this.center = center; - } - - void setFillColor(int color) { - fillColor = color; - } - - void setRadius(double radius) { - this.radius = radius; - } - - void setStrokeColor (int color) { - strokeColor = color; - } - - void setStrokeWidth (float width) { - strokeWidth = width; - } - -} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/CircleOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/CircleOptions.java deleted file mode 100644 index cc381f485f5..00000000000 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/CircleOptions.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.mapbox.mapboxsdk.annotations; - - -import com.mapbox.mapboxsdk.geometry.LatLng; - -/** - * UNIMPLEMENTED: Needs implementation in Native. - * - * https://github.com/mapbox/mapbox-gl-native/issues/1882 - * https://github.com/mapbox/mapbox-gl-native/issues/1726 - */ -class CircleOptions { - - private Circle circle; - - public CircleOptions() { - circle = new Circle(); - } - public CircleOptions center(LatLng center) { - circle.setCenter(center);; - return this; - } - - public CircleOptions fillColor(int color) { - circle.setFillColor(color); - return this; - } - - public LatLng getCenter() { - return circle.getCenter(); - } - - public int getFillColor() { - return circle.getFillColor(); - } - - public double getRadius() { - return circle.getRadius(); - } - - public int getStrokeColor () { - return circle.getStrokeColor(); - } - - public float getStrokeWidth() { - return circle.getStrokeWidth(); - } - - public CircleOptions radius(double radius) { - circle.setRadius(radius); - return this; - } - - public CircleOptions strokeColor(int color) { - circle.setStrokeColor(color); - return this; - } - - public CircleOptions strokeWidth (float width) { - circle.setStrokeWidth(width); - return this; - } - - public CircleOptions alpha(float alpha) { - circle.setAlpha(alpha); - return this; - } - - public float getAlpha() { - return circle.getAlpha(); - } - - private CircleOptions visible(boolean visible) { - circle.setVisible(visible); - return this; - } - - private boolean isVisible() { - return circle.isVisible(); - } -} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java index 4b4fdb8c102..799d01d5c04 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java @@ -30,54 +30,59 @@ final class InfoWindow { static int mSubDescriptionId = 0; static int mImageId = 0; - public InfoWindow(int layoutResId, MapView mapView) { - mMapView = new WeakReference(mapView); - mIsVisible = false; - mView = LayoutInflater.from(mapView.getContext()).inflate(layoutResId, mapView, false); + InfoWindow(int layoutResId, MapView mapView) { + View view = LayoutInflater.from(mapView.getContext()).inflate(layoutResId, mapView, false); if (mTitleId == 0) { setResIds(mapView.getContext()); } - // default behavior: close it when clicking on the tooltip: - setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent e) { - if (e.getAction() == MotionEvent.ACTION_UP) { - close(); - } - return true; - } - }); + initialize(view, mapView); + } + + InfoWindow(View view, MapView mapView) { + initialize(view, mapView); } - public InfoWindow(View view, MapView mapView) { - mMapView = new WeakReference(mapView); + private void initialize(View view, MapView mapView) { + mMapView = new WeakReference<>(mapView); mIsVisible = false; mView = view; // default behavior: close it when clicking on the tooltip: - setOnTouchListener(new View.OnTouchListener() { + mView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent e) { if (e.getAction() == MotionEvent.ACTION_UP) { - close(); + boolean handledDefaultClick = false; + MapView.OnInfoWindowClickListener onInfoWindowClickListener = + mMapView.get().getOnInfoWindowClickListener(); + if (onInfoWindowClickListener != null) { + handledDefaultClick = onInfoWindowClickListener.onMarkerClick(getBoundMarker()); + } + + if (!handledDefaultClick) { + close(); + } } return true; } }); } + /** * open the window at the specified position. * - * @param object the graphical object on which is hooked the view - * @param position to place the window on the map - * @param offsetX (&offsetY) the offset of the view to the position, in pixels. - * This allows to offset the view from the object position. + * @param boundMarker the marker on which is hooked the view + * @param position to place the window on the map + * @param offsetX (&offsetY) the offset of the view to the position, in pixels. + * This allows to offset the view from the object position. * @return this infowindow */ - public InfoWindow open(Marker object, LatLng position, int offsetX, int offsetY) { + InfoWindow open(Marker boundMarker, LatLng position, int offsetX, int offsetY) { + setBoundMarker(boundMarker); + MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT); mView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); @@ -148,42 +153,23 @@ public InfoWindow open(Marker object, LatLng position, int offsetX, int offsetY) * * @return this info window */ - public InfoWindow close() { + InfoWindow close() { if (mIsVisible) { mIsVisible = false; ((ViewGroup) mView.getParent()).removeView(mView); -// this.boundMarker.blur(); setBoundMarker(null); onClose(); } return this; } - /** - * Returns the Android view. This allows to set its content. - * - * @return the Android view - */ - public View getView() { - return mView; - } - - /** - * Returns the mapView this InfoWindow is bound to - * - * @return the mapView - */ - public MapView getMapView() { - return mMapView.get(); - } - /** * Constructs the view that is displayed when the InfoWindow opens. * This retrieves data from overlayItem and shows it in the tooltip. * * @param overlayItem the tapped overlay item */ - public void adaptDefaultMarker(Marker overlayItem) { + void adaptDefaultMarker(Marker overlayItem) { String title = overlayItem.getTitle(); ((TextView) mView.findViewById(mTitleId /*R.id.title*/)).setText(title); String snippet = overlayItem.getSnippet(); @@ -202,16 +188,16 @@ public void adaptDefaultMarker(Marker overlayItem) { */ } - public void onClose() { - //by default, do nothing + private void onClose() { + mMapView.get().deselectMarker(); } - public InfoWindow setBoundMarker(Marker boundMarker) { - mBoundMarker = new WeakReference(boundMarker); + InfoWindow setBoundMarker(Marker boundMarker) { + mBoundMarker = new WeakReference<>(boundMarker); return this; } - public Marker getBoundMarker() { + Marker getBoundMarker() { if (mBoundMarker == null) { return null; } @@ -222,7 +208,7 @@ public Marker getBoundMarker() { * Given a context, set the resource ids for the layout * of the InfoWindow. * - * @param context + * @param context the apps Context */ private static void setResIds(Context context) { String packageName = context.getPackageName(); //get application package name @@ -233,13 +219,4 @@ private static void setResIds(Context context) { .getIdentifier("id/infowindow_subdescription", null, packageName); mImageId = context.getResources().getIdentifier("id/infowindow_image", null, packageName); } - - /** - * Use to override default touch events handling on InfoWindow (ie, close automatically) - * - * @param listener New View.OnTouchListener to use - */ - public void setOnTouchListener(View.OnTouchListener listener) { - mView.setOnTouchListener(listener); - } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java index f2bb79f3694..9b0a3392523 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java @@ -7,7 +7,7 @@ import com.mapbox.mapboxsdk.R; -class InfoWindowView extends RelativeLayout{ +class InfoWindowView extends RelativeLayout { private InfoWindowTipView mTipView; @@ -24,13 +24,13 @@ public InfoWindowView(Context context, AttributeSet attrs, int defStyleAttr) { initialize(context); } - private void initialize(Context context){ + private void initialize(Context context) { LayoutInflater.from(context).inflate(R.layout.infowindow_content, this); mTipView = (InfoWindowTipView) findViewById(R.id.infowindow_tipview); } - public void setTipViewMarginLeft(int marginLeft){ - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTipView.getLayoutParams(); + void setTipViewMarginLeft(int marginLeft) { + RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTipView.getLayoutParams(); layoutParams.leftMargin = marginLeft; // This is a bit of a hack but prevents an occasional 1 pixel gap between the InfoWindow and // the tip diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java index eed66d27382..4f43f9bfa2d 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java @@ -1,26 +1,19 @@ package com.mapbox.mapboxsdk.annotations; -import android.graphics.Point; import android.support.annotation.Nullable; import android.view.View; + import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.views.MapView; public final class Marker extends Annotation { - private float anchorU; - private float anchorV; - private boolean draggable; - private boolean flat; - private float infoWindowAnchorU; - private float infoWindowAnchorV; private LatLng position; - private float rotation; private String snippet; private Sprite icon; private String title; private InfoWindow infoWindow = null; - private boolean infoWindowShown = false; private int topOffsetPixels; @@ -31,50 +24,10 @@ public final class Marker extends Annotation { super(); } - /** - * If two markers have the same LatLng, they are equal. - * - * @param other object - * @return boolean - do they have the same LatLng - */ - public boolean equals(Object other) { - if (!(other instanceof Marker)) return false; - double lat = position.getLatitude(); - double lng = position.getLongitude(); - LatLng otherPosition = ((Marker)other).getPosition(); - double otherLat = otherPosition.getLatitude(); - double otherLng = otherPosition.getLongitude(); - return (lat == otherLat && otherLng == lng); - } - - Point getAnchor() { - return new Point((int)anchorU, (int)anchorV); - } - - float getAnchorU() { - return anchorU; - } - - float getAnchorV() { - return anchorV; - } - - float getInfoWindowAnchorU() { - return infoWindowAnchorU; - } - - float getInfoWindowAnchorV() { - return infoWindowAnchorV; - } - public LatLng getPosition() { return position; } - float getRotation() { - return rotation; - } - public String getSnippet() { return snippet; } @@ -93,47 +46,17 @@ public void hideInfoWindow() { infoWindowShown = false; } - boolean isDraggable() { - return draggable; - } - - boolean isFlat() { - return flat; - } - /** * Do not use this method. Used internally by the SDK. */ - public boolean isInfoWindowShown () { + public boolean isInfoWindowShown() { return infoWindowShown; } - void setAnchor(float u, float v) { - this.anchorU = u; - this.anchorV = v; - } - - void setDraggable(boolean draggable) { - this.draggable = draggable; - } - - void setFlat(boolean flat) { - this.flat = flat; - } - - void setInfoWindowAnchor(float u, float v) { - infoWindowAnchorU = u; - infoWindowAnchorV = v; - } - void setPosition(LatLng position) { this.position = position; } - void setRotation(float rotation) { - this.rotation = rotation; - } - void setSnippet(String snippet) { this.snippet = snippet; } @@ -157,48 +80,30 @@ void setTitle(String title) { * Do not use this method. Used internally by the SDK. */ public void showInfoWindow() { - if (!isVisible() || getMapView() == null) { + if (getMapView() == null) { return; } - getInfoWindow().adaptDefaultMarker(this); - showInfoWindow(getInfoWindow()); - } - - /** - * Do not use this method. Used internally by the SDK. - */ - public void showInfoWindow(View view){ - if (!isVisible() || getMapView() == null) { - return; + MapView.InfoWindowAdapter infoWindowAdapter = getMapView().getInfoWindowAdapter(); + if (infoWindowAdapter != null) { + // end developer is using a custom InfoWindowAdapter + View content = infoWindowAdapter.getInfoWindow(this); + if (content != null) { + infoWindow = new InfoWindow(content, getMapView()); + showInfoWindow(infoWindow); + return; + } } - infoWindow = new InfoWindow(view, getMapView()); - showInfoWindow(infoWindow); + getInfoWindow().adaptDefaultMarker(this); + showInfoWindow(getInfoWindow()); } private void showInfoWindow(InfoWindow iw) { iw.open(this, getPosition(), 0, topOffsetPixels); - iw.setBoundMarker(this); infoWindowShown = true; } - /** - * Use to set a custom OnTouchListener for the InfoWindow. - * By default the InfoWindow will close on touch. - * @param listener Custom OnTouchListener - */ - public void setInfoWindowOnTouchListener(View.OnTouchListener listener) { - if (listener == null) { - return; - } - getInfoWindow().setOnTouchListener(listener); - } - - /** - * Common internal InfoWindow initialization method - * @return InfoWindow for Marker - */ private InfoWindow getInfoWindow() { if (infoWindow == null) { infoWindow = new InfoWindow(R.layout.infowindow_view, getMapView()); @@ -206,6 +111,7 @@ private InfoWindow getInfoWindow() { return infoWindow; } + /* @Override void setVisible(boolean visible) { super.setVisible(visible); @@ -213,16 +119,7 @@ void setVisible(boolean visible) { hideInfoWindow(); } } - - // TODO Method in Google Maps Android API -// public int hashCode() - - /** - * Do not use this method. Used internally by the SDK. - */ - public int getTopOffsetPixels() { - return topOffsetPixels; - } + */ /** * Do not use this method. Used internally by the SDK. @@ -230,4 +127,21 @@ public int getTopOffsetPixels() { public void setTopOffsetPixels(int topOffsetPixels) { this.topOffsetPixels = topOffsetPixels; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + Marker marker = (Marker) o; + return !(getPosition() != null ? !getPosition().equals(marker.getPosition()) : marker.getPosition() != null); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (getPosition() != null ? getPosition().hashCode() : 0); + return result; + } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java index 5fa6412c01e..f0c15906e0c 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java @@ -1,7 +1,7 @@ package com.mapbox.mapboxsdk.annotations; import android.support.annotation.Nullable; -import android.text.TextUtils; + import com.mapbox.mapboxsdk.geometry.LatLng; public final class MarkerOptions { @@ -12,57 +12,17 @@ public MarkerOptions() { marker = new Marker(); } - private MarkerOptions anchor(float u, float v) { - marker.setAnchor(u, v); - return this; - } - - private MarkerOptions draggable(boolean draggable) { - marker.setDraggable(draggable); - return this; - } - - private MarkerOptions flat(boolean flat) { - marker.setFlat(flat); - return this; - } - - private float getAnchorU() { - return marker.getAnchorU(); - } - - private float getAnchorV() { - return marker.getAnchorV(); - } - - // TODO: Implement this method of Google Maps Android API -// public BitmapDescriptor getIcon () { -// -// } - - private float getInfoWindowAnchorU() { - return marker.getInfoWindowAnchorU(); - } - - private float getInfoWindowAnchorV() { - return marker.getInfoWindowAnchorV(); - } - /** * Do not use this method. Used internally by the SDK. */ public Marker getMarker() { - return (Marker) marker; + return marker; } public LatLng getPosition() { return marker.getPosition(); } - private float getRotation() { - return marker.getRotation(); - } - public String getSnippet() { return marker.getSnippet(); } @@ -75,33 +35,11 @@ public Sprite getIcon() { return marker.getIcon(); } - private MarkerOptions infoWindowAnchor(float u, float v) { - marker.setInfoWindowAnchor(u, v); - return this; - } - - private boolean isDraggable() { - return marker.isDraggable(); - } - - private boolean isFlat() { - return marker.isFlat(); - } - - private boolean isVisible() { - return marker.isVisible(); - } - public MarkerOptions position(LatLng position) { marker.setPosition(position); return this; } - private MarkerOptions rotation(float rotation) { - marker.setRotation(rotation); - return this; - } - public MarkerOptions snippet(String snippet) { marker.setSnippet(snippet); return this; @@ -117,26 +55,30 @@ public MarkerOptions title(String title) { return this; } - private MarkerOptions visible(boolean visible) { - marker.setVisible(visible); - return this; - } - - private MarkerOptions alpha(float alpha) { - marker.setAlpha(alpha); - return this; - } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - private float getAlpha() { - return marker.getAlpha(); - } + MarkerOptions marker = (MarkerOptions) o; - // TODO: Implement this method of Google Maps Android API -// public MarkerOptions icon(BitmapDescriptor icon) { -// -// } + if (getPosition() != null ? !getPosition().equals(marker.getPosition()) : marker.getPosition() != null) + return false; + if (getSnippet() != null ? !getSnippet().equals(marker.getSnippet()) : marker.getSnippet() != null) + return false; + if (getIcon() != null ? !getIcon().equals(marker.getIcon()) : marker.getIcon() != null) + return false; + return !(getTitle() != null ? !getTitle().equals(marker.getTitle()) : marker.getTitle() != null); - // TODO: Implement this method of Google Maps Android API -// public void writeToParcel (Parcel out, int flags) + } + @Override + public int hashCode() { + int result = 1; + result = 31 * result + (getPosition() != null ? getPosition().hashCode() : 0); + result = 31 * result + (getSnippet() != null ? getSnippet().hashCode() : 0); + result = 31 * result + (getIcon() != null ? getIcon().hashCode() : 0); + result = 31 * result + (getTitle() != null ? getTitle().hashCode() : 0); + return result; + } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java index 774a09dc05f..5c1dfb119f9 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java @@ -8,6 +8,7 @@ public abstract class MultiPoint extends Annotation { private List points; + private float alpha = 1.0f; protected MultiPoint() { super(); @@ -28,7 +29,7 @@ public List getPoints() { * of the points, so further mutations to points will have no effect * on this polyline. * - * @param points + * @param points the points of the polyline */ void setPoints(List points) { this.points = new ArrayList<>(points); @@ -38,20 +39,11 @@ void addPoint(LatLng point) { points.add(point); } + public float getAlpha() { + return alpha; + } - // TODO: Implement hashCode of Google Maps Android API -// public int hashCode() { -// -// } - - // TODO: Implement isGeodesic of Google Maps Android API -// public boolean isGeodesic() { -// -// } - - // TODO: Implement setGeodesic of Google Maps Android API -// public void setGeodesic(boolean geodesic) { -// -// } - + void setAlpha(float alpha) { + this.alpha = alpha; + } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java index 1f4e7de2498..32258943ab7 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java @@ -1,6 +1,5 @@ package com.mapbox.mapboxsdk.annotations; - import android.graphics.Color; import com.mapbox.mapboxsdk.geometry.LatLng; @@ -11,92 +10,25 @@ public final class Polygon extends MultiPoint { private int fillColor = Color.BLACK; // default fillColor is black - private float strokeAlpha = 1; private int strokeColor = Color.BLACK; // default strokeColor is black - private float strokeWidth = 10; // As specified by Google API Docs (in pixels) - - private List> holes; Polygon() { super(); - holes = new ArrayList<>(); } public int getFillColor() { return fillColor; } - List> getHoles () { - return new ArrayList<>(holes); - } - public int getStrokeColor() { return strokeColor; } - /** - * UNIMPLEMENTED: Needs implementation in Native. - * https://github.com/mapbox/mapbox-gl-native/issues/1737 - * @return stroke width as float - */ - float getStrokeWidth() { - return strokeWidth; - } - - private void setFillAlpha(float alpha) { - this.setAlpha(alpha); - } - void setFillColor(int color) { fillColor = color; } - /** - * Sets the holes of this polygon. This method will take a copy of the holes, - * so further mutations to holes parameter will have no effect on this polygon. - * - * @param holes - */ - void setHoles(List> holes) { - this.holes = new ArrayList<>(); - for (List hole : holes) { - this.holes.add(new ArrayList<>(hole)); - } - } - - void addHole(List hole) { - holes.add(hole); - } - - /** - * Sets the alpha (opacity) of the stroke - * - * UNIMPLEMENTED: Needs implementation in Native. - */ - void setStrokeAlpha(float alpha) { - strokeAlpha = alpha; - } - void setStrokeColor(int color) { strokeColor = color; } - - /** - * UNIMPLEMENTED: Needs implementation in Native. - * https://github.com/mapbox/mapbox-gl-native/issues/1737 - */ - void setStrokeWidth(float width) { - strokeWidth = width; - } - - - // TODO: Implement equals of Google Maps Android API -// public boolean equals (Object other) { -// -// } - - // TODO: Implement hashCode of Google Maps Android API -// public int hashCode () { -// -// } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java index 323dff7da16..42e80edc2c9 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java @@ -3,7 +3,6 @@ import com.mapbox.mapboxsdk.geometry.LatLng; -import java.util.ArrayList; import java.util.List; public final class PolygonOptions { @@ -33,22 +32,6 @@ public PolygonOptions addAll(Iterable points) { return this; } - /** - * UNIMPLEMENTED: Needs implementation in Native. - * https://github.com/mapbox/mapbox-gl-native/issues/1729 - * - * @param points - an iterable (list) of points for cutting a hole - * @return PolygonOptions - the options object - */ - private PolygonOptions addHole (Iterable points) { - List hole = new ArrayList<>(); - for (LatLng point : points) { - hole.add(point); - } - polygon.addHole(hole); - return this; - } - public PolygonOptions alpha(float alpha) { polygon.setAlpha(alpha); return this; @@ -73,16 +56,6 @@ public int getFillColor() { return polygon.getFillColor(); } - /** - * UNIMPLEMENTED: Needs implementation in Native. - * https://github.com/mapbox/mapbox-gl-native/issues/1729 - * - * @return a list of lists of points for cutting holes - */ - private List> getHoles() { - return polygon.getHoles(); - } - /** * Do not use this method. Used internally by the SDK. */ @@ -90,20 +63,6 @@ public Polygon getPolygon() { return polygon; } - public int getStrokeColor() { - return polygon.getStrokeColor(); - } - - /** - * UNIMPLEMENTED: Needs implementation in Native. - * https://github.com/mapbox/mapbox-gl-native/issues/1737 - * - * @return stroke width as float - */ - private float getStrokeWidth() { - return polygon.getStrokeWidth(); - } - /** * Sets the color of the stroke of the polygon. * @@ -115,24 +74,8 @@ public PolygonOptions strokeColor(int color) { return this; } - /** - * UNIMPLEMENTED: Needs implementation in Native. - * https://github.com/mapbox/mapbox-gl-native/issues/1737 - * - * @return stroke width as float - */ - private PolygonOptions strokeWidth(float width) { - polygon.setStrokeWidth(width); - return this; - } - - private PolygonOptions visible(boolean visible) { - polygon.setVisible(visible); - return this; - } - - private boolean isVisible() { - return polygon.isVisible(); + public int getStrokeColor() { + return polygon.getStrokeColor(); } public List getPoints() { @@ -140,9 +83,26 @@ public List getPoints() { return polygon.getPoints(); } - // TODO: Implement writeToParcel of Google Maps Android API -// public void writeToParcel(Parcel out, int flags) { -// -// } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PolygonOptions polygon = (PolygonOptions) o; + + if (Float.compare(polygon.getAlpha(), getAlpha()) != 0) return false; + if (getFillColor() != polygon.getFillColor()) return false; + if (getStrokeColor() != polygon.getStrokeColor()) return false; + return !(getPoints() != null ? !getPoints().equals(polygon.getPoints()) : polygon.getPoints() != null); + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0); + result = 31 * result + getFillColor(); + result = 31 * result + getStrokeColor(); + result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0); + return result; + } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polyline.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polyline.java index b7887c8c9a5..331974c9c66 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polyline.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polyline.java @@ -19,7 +19,6 @@ public float getWidth() { return width; } - /** * Sets the color of the polyline. * @@ -29,7 +28,6 @@ void setColor(int color) { this.color = color; } - /** * Sets the width of the polyline. * @@ -38,9 +36,4 @@ void setColor(int color) { void setWidth(float width) { this.width = width; } - - // TODO: Implement equals of Google Maps Android API -// public boolean equals(Object other) { -// -// } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java index bba9ed0527e..089646696d8 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java @@ -65,15 +65,6 @@ public float getWidth() { return polyline.getWidth(); } - PolylineOptions visible(boolean visible) { - polyline.setVisible(visible); - return this; - } - - private boolean isVisible() { - return polyline.isVisible(); - } - /** * Sets the width of the polyline. * @@ -90,9 +81,26 @@ public List getPoints() { return polyline.getPoints(); } - // TODO: Implement writeToParcel of Google Maps Android API -// public void writeToParcel(Parcel out, int flags) { -// -// } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PolylineOptions polyline = (PolylineOptions) o; + + if (Float.compare(polyline.getAlpha(), getAlpha()) != 0) return false; + if (getColor() != polyline.getColor()) return false; + if (Float.compare(polyline.getWidth(), getWidth()) != 0) return false; + return !(getPoints() != null ? !getPoints().equals(polyline.getPoints()) : polyline.getPoints() != null); + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0); + result = 31 * result + getColor(); + result = 31 * result + (getWidth() != +0.0f ? Float.floatToIntBits(getWidth()) : 0); + result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0); + return result; + } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/SpriteFactory.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/SpriteFactory.java index 3178ef1553e..ae07050ef61 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/SpriteFactory.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/SpriteFactory.java @@ -3,9 +3,7 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.graphics.drawable.BitmapDrawable; import android.os.Build; -import android.support.v4.content.ContextCompat; import android.util.DisplayMetrics; import android.view.WindowManager; @@ -17,13 +15,12 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.lang.ref.WeakReference; -import java.util.Map; public final class SpriteFactory { private static final String SPRITE_ID_PREFIX = "com.mapbox.sprites.sprite_"; + // TODO make weak private MapView mMapView; private Sprite mDefaultMarker; private BitmapFactory.Options mOptions; @@ -98,7 +95,7 @@ public Sprite fromPath(String absolutePath) { } public Sprite fromFile(String fileName) { - FileInputStream is = null; + FileInputStream is; try { is = mMapView.getContext().openFileInput(fileName); } catch (FileNotFoundException e) { diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java index 7f036aca493..b2a0a02b15f 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java @@ -25,6 +25,14 @@ public LatLng[] newArray(int size) { private double longitude; private double altitude = 0.0; + /** + * Construct a new latitude, longitude point at (0, 0) + */ + public LatLng() { + this.latitude = 0.0; + this.longitude = 0.0; + } + /** * Construct a new latitude, longitude point given float arguments * @param latitude Latitude in degrees diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java index 8822d7c036c..9e453a391ce 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngZoom.java @@ -19,6 +19,11 @@ public LatLngZoom[] newArray(int size) { private double zoom; + public LatLngZoom() { + super(); + this.zoom = 0.0; + } + public LatLngZoom(double latitude, double longitude, double zoom) { super(latitude, longitude); this.zoom = zoom; diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java index b4e4e7b77ed..477235e48c1 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java @@ -221,6 +221,7 @@ public final class MapView extends FrameLayout { // Used to manage marker click event listeners private OnMarkerClickListener mOnMarkerClickListener; + private OnInfoWindowClickListener mOnInfoWindowClickListener; // Used to manage FPS change event listeners private OnFpsChangedListener mOnFpsChangedListener; @@ -432,7 +433,22 @@ public interface OnMarkerClickListener { * Called when the user clicks on a marker. * * @param marker The marker the user clicked on. - * @return If true the listener has consumed the event and the {@link InfoWindow} will not be shown. + * @return If true the listener has consumed the event and the info window will not be shown. + */ + boolean onMarkerClick(@NonNull Marker marker); + } + + /** + * Interface definition for a callback to be invoked when the user clicks on an info window. + * + * @see MapView#setOnInfoWindowClickListener(OnInfoWindowClickListener) + */ + public interface OnInfoWindowClickListener { + /** + * Called when the user clicks on an info window. + * + * @param marker The marker of the info window the user clicked on. + * @return If true the listener has consumed the event and the info window will not be closed. */ boolean onMarkerClick(@NonNull Marker marker); } @@ -453,17 +469,17 @@ public interface OnMapChangedListener { } /** - * Interface definition for a callback to be invoked when an {@link InfoWindow} will be shown. + * Interface definition for a callback to be invoked when an info window will be shown. * * @see MapView#setInfoWindowAdapter(InfoWindowAdapter) */ public interface InfoWindowAdapter { /** - * Called when an {@link InfoWindow} will be shown as a result of a marker click. + * Called when an info window will be shown as a result of a marker click. * * @param marker The marker the user clicked on. - * @return View to be shown as a {@code InfoWindow}. If null is returned the default - * {@code InfoWindow} will be shown. + * @return View to be shown as a info window. If null is returned the default + * info window will be shown. */ @Nullable View getInfoWindow(@NonNull Marker marker); @@ -1777,7 +1793,8 @@ public List addPolygons(@NonNull List polygonOptionsLis throw new NullPointerException("polygonOptionsList is null"); } - List polygons = new ArrayList<>(polygonOptionsList.size()); + int count = polygonOptionsList.size(); + List polygons = new ArrayList<>(count); for (PolygonOptions polygonOptions : polygonOptionsList) { polygons.add(polygonOptions.getPolygon()); } @@ -1785,8 +1802,7 @@ public List addPolygons(@NonNull List polygonOptionsLis long[] ids = mNativeMapView.addPolygons(polygons); Polygon p; - int count = polygons.size(); - for (int i = 0; i < polygons.size(); i++) { + for (int i = 0; i < count; i++) { p = polygons.get(i); p.setId(ids[i]); p.setMapView(this); @@ -1839,9 +1855,10 @@ public void removeAnnotations(@NonNull List annotationList) { */ @UiThread public void removeAllAnnotations() { + int count = mAnnotations.size(); long[] ids = new long[mAnnotations.size()]; - for (int i = 0; i < mAnnotations.size(); i++) { + for (int i = 0; i < count; i++) { Annotation annotation = mAnnotations.get(i); long id = annotation.getId(); ids[i] = id; @@ -1879,7 +1896,8 @@ private List getMarkersInBounds(@NonNull BoundingBox bbox) { } List annotations = new ArrayList<>(ids.length); - for (int i = 0; i < mAnnotations.size(); i++) { + int count = mAnnotations.size(); + for (int i = 0; i < count; i++) { Annotation annotation = mAnnotations.get(i); if (annotation instanceof Marker && idsList.contains(annotation.getId())) { annotations.add((Marker) annotation); @@ -1914,9 +1932,18 @@ public double getMetersPerPixelAtLatitude(@FloatRange(from = -180, to = 180) dou return mNativeMapView.getMetersPerPixelAtLatitude(latitude, getZoomLevel()) / mScreenDensity; } - private void selectMarker(Marker marker) { + /** + * Selects a marker. The selected marker will have it's info window opened. + * Any other open info windows will be closed. + *

+ * Selecting an already selected marker will have no effect. + * + * @param marker The marker to select. + */ + @UiThread + public void selectMarker(@NonNull Marker marker) { if (marker == null) { - return; + throw new NullPointerException("marker is null"); } if (marker == mSelectedMarker) { @@ -1936,25 +1963,17 @@ private void selectMarker(Marker marker) { // default behaviour // Can't do this as InfoWindow will get hidden //setCenterCoordinate(marker.getPosition(), true); - showInfoWindow(marker); + marker.showInfoWindow(); } mSelectedMarker = marker; } - private void showInfoWindow(Marker marker) { - if (mInfoWindowAdapter != null) { - // end developer is using a custom InfoWindowAdapter - View content = mInfoWindowAdapter.getInfoWindow(marker); - if (content != null) { - marker.showInfoWindow(content); - } - } else { - marker.showInfoWindow(); - } - } - - private void deselectMarker() { + /** + * Deselects any currently selected marker. The selected marker will have it's info window closed. + */ + @UiThread + public void deselectMarker() { if (mSelectedMarker != null) { if (mSelectedMarker.isInfoWindowShown()) { mSelectedMarker.hideInfoWindow(); @@ -1963,6 +1982,16 @@ private void deselectMarker() { } } + /** + * Gets the currently selected marker. + * @return The currently selected marker. + */ + @UiThread + @Nullable + public Marker getSelectedMarker() { + return mSelectedMarker; + } + private void adjustTopOffsetPixels() { int count = mAnnotations.size(); for (int i = 0; i < count; i++) { @@ -1976,8 +2005,10 @@ private void adjustTopOffsetPixels() { if (mSelectedMarker != null) { if (mSelectedMarker.isInfoWindowShown()) { - mSelectedMarker.hideInfoWindow(); - showInfoWindow(mSelectedMarker); + Marker temp = mSelectedMarker; + temp.hideInfoWindow(); + temp.showInfoWindow(); + mSelectedMarker = temp; } } } @@ -2260,9 +2291,7 @@ public boolean onSingleTapConfirmed(MotionEvent e) { } else { // deselect any selected marker - if (mSelectedMarker != null) { - deselectMarker(); - } + deselectMarker(); // notify app of map click if (mOnMapClickListener != null) { @@ -2837,18 +2866,32 @@ protected void onMapChanged(int mapChange) { } /** - * Sets a custom renderer for the contents of {@link InfoWindow}. + * Sets a custom renderer for the contents of info window. *

- * When set your callback is invoked when an {@code InfoWindow} is about to be shown. By returning - * a custom {@link View}, the default {@code InfoWindow} will be replaced. + * When set your callback is invoked when an info window is about to be shown. By returning + * a custom {@link View}, the default info window will be replaced. * - * @param infoWindowAdapter The callback to be invoked when an {@link InfoWindow} will be shown. + * @param infoWindowAdapter The callback to be invoked when an info window will be shown. + * To unset the callback, use null. */ @UiThread public void setInfoWindowAdapter(@Nullable InfoWindowAdapter infoWindowAdapter) { mInfoWindowAdapter = infoWindowAdapter; } + /** + * Gets the callback to be invoked when an info window will be shown. + * + * @return The callback to be invoked when an info window will be shown. + */ + @UiThread + @Nullable + public InfoWindowAdapter getInfoWindowAdapter() { + return mInfoWindowAdapter; + } + + + /** * Sets a callback that's invoked on every frame rendered to the map view. * @@ -2929,6 +2972,28 @@ public void setOnMarkerClickListener(@Nullable OnMarkerClickListener listener) { mOnMarkerClickListener = listener; } + /** + * Sets a callback that's invoked when the user clicks on an info window. + * + * @return The callback that's invoked when the user clicks on an info window. + */ + @UiThread + @Nullable + public OnInfoWindowClickListener getOnInfoWindowClickListener() { + return mOnInfoWindowClickListener; + } + + /** + * Sets a callback that's invoked when the user clicks on an info window. + * + * @param listener The callback that's invoked when the user clicks on an info window. + * To unset the callback, use null. + */ + @UiThread + public void setOnInfoWindowClickListener(@Nullable OnInfoWindowClickListener listener) { + mOnInfoWindowClickListener = listener; + } + // // User location // diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java index 3d2416ecd4d..8ac065f60dd 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java @@ -108,6 +108,7 @@ private void initialize(MapView mapView, Context context) { // Setup the custom paint Resources resources = context.getResources(); mDensity = resources.getDisplayMetrics().density; + mMarkerCoordinate = new LatLng(0.0, 0.0); mMarkerScreenPoint = new PointF(); mMarkerScreenMatrix = new Matrix(); @@ -305,7 +306,6 @@ private void setLocation(Location location) { cancelAnimations(); mUserLocation = null; - mMarkerCoordinate = null; return; } diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java index 361e6fd443e..999d38d1d93 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java @@ -137,11 +137,20 @@ public void onMapClick(@NonNull LatLng point) { mMapView.setOnMarkerClickListener(new MapView.OnMarkerClickListener() { @Override public boolean onMarkerClick(@NonNull Marker marker) { - Snackbar.make(mCoordinatorLayout, "Custom Marker Click Listener", Snackbar.LENGTH_SHORT).show(); + Snackbar.make(mCoordinatorLayout, "Marker Click Listener for " + marker.getTitle(), Snackbar.LENGTH_SHORT).show(); return false; } }); + mMapView.setOnInfoWindowClickListener(new MapView.OnInfoWindowClickListener() { + @Override + public boolean onMarkerClick(@NonNull Marker marker) { + Snackbar.make(mCoordinatorLayout, "InfoWindow Click Listener for " + marker.getTitle(), Snackbar.LENGTH_SHORT).show(); + marker.hideInfoWindow(); + return true; + } + }); + mMapView.setOnMyLocationChangeListener(new MapView.OnMyLocationChangeListener() { @Override public void onMyLocationChange(@Nullable Location location) { @@ -430,18 +439,7 @@ private void addMarkers() { final MarkerOptions cheeseRoom = generateMarker("Cheese Room", "The only air conditioned room on the property", dogIcon, 38.531577, -122.010646); markerOptionsList.add(cheeseRoom); - List markers = mMapView.addMarkers(markerOptionsList); - - // need to call this after adding markers to map, click event hook into InfoWindow needs refactoring - final Marker backLotMarker = markers.get(0); - backLotMarker.setInfoWindowOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View view, MotionEvent motionEvent) { - Toast.makeText(getApplicationContext(), "Custom Info Touch Listener!!", Toast.LENGTH_SHORT).show(); - backLotMarker.hideInfoWindow(); - return true; - } - }); + List markers = mMapView.addMarkers(markerOptionsList); } private MarkerOptions generateMarker(String title, String snippet, Sprite icon, double lat, double lng){ diff --git a/include/mbgl/android/jni.hpp b/include/mbgl/android/jni.hpp index 8759e0f03b9..89bda3c7ed0 100644 --- a/include/mbgl/android/jni.hpp +++ b/include/mbgl/android/jni.hpp @@ -59,19 +59,15 @@ extern jfieldID markerIconId; extern jclass polylineClass; extern jfieldID polylineAlphaId; -extern jfieldID polylineVisibleId; extern jfieldID polylineColorId; extern jfieldID polylineWidthId; extern jfieldID polylinePointsId; extern jclass polygonClass; extern jfieldID polygonAlphaId; -extern jfieldID polygonVisibleId; extern jfieldID polygonFillColorId; extern jfieldID polygonStrokeColorId; -extern jfieldID polygonStrokeWidthId; extern jfieldID polygonPointsId; -extern jfieldID polygonHolesId; extern jclass runtimeExceptionClass; extern jclass nullPointerExceptionClass;