From a2dbec82ddd4e5edd207dc408f196cce90ecd779 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Fri, 17 Jun 2016 16:51:32 +0200 Subject: [PATCH] [android] Fix info window placement on programatic marker select Fixes #5348 --- .../annotations/MarkerViewManager.java | 45 ++++++++++++++++--- .../com/mapbox/mapboxsdk/maps/MapboxMap.java | 5 +++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index f99516bb0bc..a18b864cfe4 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -8,6 +8,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.animation.AnimationUtils; import android.widget.ImageView; import com.mapbox.mapboxsdk.R; @@ -376,11 +377,7 @@ public void onClick(final View v) { } if (!clickHandled) { - // InfoWindow offset - int infoWindowOffsetX = (int) ((adaptedView.getWidth() * marker.getInfoWindowAnchorU()) - marker.getOffsetX()); - int infoWindowOffsetY = (int) ((adaptedView.getHeight() * marker.getInfoWindowAnchorV()) - marker.getOffsetY()); - marker.setTopOffsetPixels(infoWindowOffsetY); - marker.setRightOffsetPixels(infoWindowOffsetX); + ensureInfoWindowOffset(marker); select(marker, v, adapter); } } @@ -397,6 +394,44 @@ public void onClick(final View v) { } } + //TODO: This whole method is a stopgap for: https://github.com/mapbox/mapbox-gl-native/issues/5384 + public void ensureInfoWindowOffset(MarkerView marker) { + View view = null; + if (markerViewMap.containsKey(marker)) { + view = markerViewMap.get(marker); + } else { + for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) { + if (adapter.getMarkerClass().equals(marker.getClass())) { + View convertView = (View) adapter.getViewReusePool().acquire(); + view = adapter.getView(marker, convertView, mapView); + break; + } + } + } + + if (view != null) { + //Ensure the marker's view is measured first + if (view.getMeasuredWidth() == 0) { + view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); + } + + // update position on map + if (marker.getOffsetX() == -1) { + PointF point = mapboxMap.getProjection().toScreenLocation(marker.getPosition()); + int x = (int) (marker.getAnchorU() * view.getMeasuredWidth()); + int y = (int) (marker.getAnchorV() * view.getMeasuredHeight()); + marker.setOffsetX(x); + marker.setOffsetY(y); + } + + // InfoWindow offset + int infoWindowOffsetX = (int) ((view.getMeasuredWidth() * marker.getInfoWindowAnchorU()) - marker.getOffsetX()); + int infoWindowOffsetY = (int) ((view.getMeasuredHeight() * marker.getInfoWindowAnchorV()) - marker.getOffsetY()); + marker.setTopOffsetPixels(infoWindowOffsetY); + marker.setRightOffsetPixels(infoWindowOffsetX); + } + } + /** * Default MarkerViewAdapter used for base class of MarkerView to adapt a MarkerView to an ImageView */ diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index c26b0795262..b0df57fe1d1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -1142,6 +1142,11 @@ public void selectMarker(@NonNull Marker marker) { } if (!handledDefaultClick) { + + if (marker instanceof MarkerView) { + mMarkerViewManager.ensureInfoWindowOffset((MarkerView) marker); + } + if (isInfoWindowValidForMarker(marker) || getInfoWindowAdapter() != null) { mInfoWindows.add(marker.showInfoWindow(this, mMapView)); }