Merge branch 'master' into 2244-texture-view
# Conflicts: # android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java
This commit is contained in:
@@ -2,8 +2,7 @@ package com.mapbox.mapboxgl.annotations;
|
||||
|
||||
import com.mapbox.mapboxgl.views.MapView;
|
||||
|
||||
|
||||
public abstract class Annotation {
|
||||
public abstract class Annotation implements Comparable<Annotation> {
|
||||
|
||||
/**
|
||||
* The annotation id
|
||||
@@ -11,7 +10,7 @@ public abstract class Annotation {
|
||||
* Internal C++ id is stored as unsigned int.
|
||||
*/
|
||||
protected long id = -1; // -1 unless added to a MapView
|
||||
private MapView mapView;
|
||||
protected MapView mapView;
|
||||
|
||||
float alpha = 1.0f;
|
||||
boolean visible = true;
|
||||
@@ -60,4 +59,35 @@ public abstract class Annotation {
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (id < annotation.getId()) {
|
||||
return 1;
|
||||
} else if (id > annotation.getId()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Equal
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
package com.mapbox.mapboxgl.annotations;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import com.mapbox.mapboxgl.geometry.LatLng;
|
||||
import com.mapbox.mapboxgl.views.MapView;
|
||||
|
||||
/**
|
||||
* A tooltip view
|
||||
*/
|
||||
public class InfoWindow {
|
||||
|
||||
private Marker boundMarker;
|
||||
private MapView mMapView;
|
||||
private boolean mIsVisible;
|
||||
protected View mView;
|
||||
|
||||
static int mTitleId = 0;
|
||||
static int mDescriptionId = 0;
|
||||
static int mSubDescriptionId = 0;
|
||||
static int mImageId = 0;
|
||||
|
||||
public InfoWindow(int layoutResId, MapView mapView) {
|
||||
mMapView = mapView;
|
||||
mIsVisible = false;
|
||||
Context context = mapView.getContext();
|
||||
LayoutInflater inflater =
|
||||
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mView = inflater.inflate(layoutResId, (ViewGroup) 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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public InfoWindow(View view, MapView mapView) {
|
||||
mMapView = mapView;
|
||||
mIsVisible = false;
|
||||
ViewGroup parent = (ViewGroup) mapView.getParent();
|
||||
Context context = mapView.getContext();
|
||||
LayoutInflater inflater =
|
||||
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mView = view;
|
||||
|
||||
// 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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return this infowindow
|
||||
*/
|
||||
public InfoWindow open(Marker object, LatLng position, int offsetX, int offsetY) {
|
||||
onOpen(object);
|
||||
MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT);
|
||||
mView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
|
||||
PointF coords = mMapView.toScreenLocation(position);
|
||||
double y = mMapView.getTopOffsetPixelsForAnnotationSymbol(object.sprite);
|
||||
y = y * mMapView.getScreenDensity();
|
||||
|
||||
// Flip y coordinate as Android view origin is upper left corner
|
||||
coords.y = mMapView.getHeight() - coords.y;
|
||||
lp.leftMargin = (int) coords.x - (mView.getMeasuredWidth() / 2);
|
||||
// Add y because it's a negative value
|
||||
lp.topMargin = (int) coords.y - mView.getMeasuredHeight() + (int) y;
|
||||
|
||||
close(); //if it was already opened
|
||||
mMapView.addView(mView, lp);
|
||||
mIsVisible = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close this InfoWindow if it is visible, otherwise don't do anything.
|
||||
*
|
||||
* @return this info window
|
||||
*/
|
||||
public 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 onOpen(Marker overlayItem) {
|
||||
String title = overlayItem.getTitle();
|
||||
((TextView) mView.findViewById(mTitleId /*R.id.title*/)).setText(title);
|
||||
String snippet = overlayItem.getSnippet();
|
||||
((TextView) mView.findViewById(mDescriptionId /*R.id.description*/)).setText(snippet);
|
||||
|
||||
/*
|
||||
//handle sub-description, hiding or showing the text view:
|
||||
TextView subDescText = (TextView) mView.findViewById(mSubDescriptionId);
|
||||
String subDesc = overlayItem.getSubDescription();
|
||||
if ("".equals(subDesc)) {
|
||||
subDescText.setVisibility(View.GONE);
|
||||
} else {
|
||||
subDescText.setText(subDesc);
|
||||
subDescText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void onClose() {
|
||||
//by default, do nothing
|
||||
}
|
||||
|
||||
public InfoWindow setBoundMarker(Marker aBoundMarker) {
|
||||
this.boundMarker = aBoundMarker;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Marker getBoundMarker() {
|
||||
return boundMarker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a context, set the resource ids for the layout
|
||||
* of the InfoWindow.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
private static void setResIds(Context context) {
|
||||
String packageName = context.getPackageName(); //get application package name
|
||||
mTitleId = context.getResources().getIdentifier("id/infowindow_title", null, packageName);
|
||||
mDescriptionId =
|
||||
context.getResources().getIdentifier("id/infowindow_description", null, packageName);
|
||||
mSubDescriptionId = context.getResources()
|
||||
.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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.mapbox.mapboxgl.annotations;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
public class InfoWindowTipView extends View {
|
||||
|
||||
private Paint mPaint;
|
||||
private Path mPath;
|
||||
|
||||
public InfoWindowTipView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
mPath = new Path();
|
||||
|
||||
this.mPaint = new Paint();
|
||||
this.mPaint.setColor(Color.WHITE);
|
||||
this.mPaint.setAntiAlias(true);
|
||||
this.mPaint.setStrokeWidth(0.0f);
|
||||
this.mPaint.setStyle(Paint.Style.FILL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
int height = getMeasuredHeight();
|
||||
int width = getMeasuredWidth();
|
||||
|
||||
mPath.rewind();
|
||||
mPath.moveTo((width / 2) - height, 0);
|
||||
mPath.lineTo((width / 2) + height, 0);
|
||||
mPath.lineTo((width / 2), height);
|
||||
mPath.lineTo((width / 2) - height, 0);
|
||||
canvas.drawPath(mPath, this.mPaint);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.mapbox.mapboxgl.annotations;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.view.View;
|
||||
import com.mapbox.mapboxgl.geometry.LatLng;
|
||||
|
||||
import com.mapbox.mapboxgl.views.R;
|
||||
|
||||
public class Marker extends Annotation {
|
||||
|
||||
@@ -16,10 +18,16 @@ public class Marker extends Annotation {
|
||||
String snippet;
|
||||
String sprite = "default_marker";
|
||||
String title;
|
||||
private InfoWindow infoWindow = null;
|
||||
|
||||
private boolean infoWindowShown = false;
|
||||
|
||||
public Marker() {}
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Marker() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* If two markers have the same LatLng, they are equal.
|
||||
@@ -41,6 +49,10 @@ public class Marker extends Annotation {
|
||||
return alpha;
|
||||
}
|
||||
|
||||
public Point getAnchor() {
|
||||
return new Point((int)anchorU, (int)anchorV);
|
||||
}
|
||||
|
||||
public float getAnchorU() {
|
||||
return anchorU;
|
||||
}
|
||||
@@ -66,7 +78,7 @@ public class Marker extends Annotation {
|
||||
}
|
||||
|
||||
public void hideInfoWindow() {
|
||||
//TODO hideInfoWindow
|
||||
infoWindow.close();
|
||||
infoWindowShown = false;
|
||||
}
|
||||
|
||||
@@ -82,33 +94,33 @@ public class Marker extends Annotation {
|
||||
return infoWindowShown;
|
||||
}
|
||||
|
||||
void setAnchor(float u, float v) {
|
||||
public void setAnchor(float u, float v) {
|
||||
this.anchorU = u;
|
||||
this.anchorV = v;
|
||||
}
|
||||
|
||||
void setDraggable(boolean draggable) {
|
||||
public void setDraggable(boolean draggable) {
|
||||
this.draggable = draggable;
|
||||
}
|
||||
|
||||
void setFlat(boolean flat) {
|
||||
public void setFlat(boolean flat) {
|
||||
this.flat = flat;
|
||||
}
|
||||
|
||||
void setInfoWindowAnchor(float u, float v) {
|
||||
public void setInfoWindowAnchor(float u, float v) {
|
||||
infoWindowAnchorU = u;
|
||||
infoWindowAnchorV = v;
|
||||
}
|
||||
|
||||
void setPosition(LatLng latlng) {
|
||||
public void setPosition(LatLng latlng) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
void setRotation(float rotation) {
|
||||
public void setRotation(float rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
void setSnippet(String snippet) {
|
||||
public void setSnippet(String snippet) {
|
||||
this.snippet = snippet;
|
||||
}
|
||||
|
||||
@@ -120,18 +132,55 @@ public class Marker extends Annotation {
|
||||
*
|
||||
* @param sprite
|
||||
*/
|
||||
void setSprite(String sprite) {
|
||||
public void setSprite(String sprite) {
|
||||
this.sprite = sprite;
|
||||
}
|
||||
|
||||
void setTitle(String title) {
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
void showInfoWindow() {
|
||||
public void showInfoWindow() {
|
||||
|
||||
if (!isVisible() || mapView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
getInfoWindow().open(this, getPosition(), (int) anchorU, (int) anchorV);
|
||||
getInfoWindow().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, mapView);
|
||||
}
|
||||
return infoWindow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
super.setVisible(visible);
|
||||
if (!visible && infoWindowShown) {
|
||||
hideInfoWindow();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Method in Google Maps Android API
|
||||
// public int hashCode()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.mapbox.mapboxgl.views;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@@ -11,6 +10,7 @@ import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.hardware.GeomagneticField;
|
||||
import android.hardware.Sensor;
|
||||
@@ -27,7 +27,6 @@ import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.view.GestureDetectorCompat;
|
||||
import android.support.v4.view.ScaleGestureDetectorCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.Gravity;
|
||||
import android.view.ScaleGestureDetector;
|
||||
@@ -100,6 +99,8 @@ public class MapView extends FrameLayout implements LocationListener {
|
||||
* Every annotation that has been added to the map.
|
||||
*/
|
||||
private List<Annotation> mAnnotations = new ArrayList<>();
|
||||
private List<Annotation> mAnnotationsNearLastTap = new ArrayList<>();
|
||||
private Annotation mSelectedAnnotation = null;
|
||||
|
||||
//
|
||||
// Instance members
|
||||
@@ -479,6 +480,9 @@ public class MapView extends FrameLayout implements LocationListener {
|
||||
private void removeAnnotationsWithId(long annotationId){
|
||||
for (Iterator<Annotation> iterator = mAnnotations.iterator(); iterator.hasNext();) {
|
||||
Annotation annotation = iterator.next();
|
||||
if (annotation instanceof Marker) {
|
||||
((Marker)annotation).hideInfoWindow();
|
||||
}
|
||||
if (annotation.getId() == annotationId) {
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -486,6 +490,9 @@ public class MapView extends FrameLayout implements LocationListener {
|
||||
}
|
||||
|
||||
public void removeAnnotation(Annotation annotation) {
|
||||
if (annotation instanceof Marker) {
|
||||
((Marker)annotation).hideInfoWindow();
|
||||
}
|
||||
long id = annotation.getId();
|
||||
mNativeMapView.removeAnnotation(id);
|
||||
mAnnotations.remove(annotation);
|
||||
@@ -499,8 +506,12 @@ public class MapView extends FrameLayout implements LocationListener {
|
||||
public void removeAnnotations() {
|
||||
long[] ids = new long[mAnnotations.size()];
|
||||
for(int i = 0; i < mAnnotations.size(); i++) {
|
||||
long id = mAnnotations.get(i).getId();
|
||||
Annotation annotation = mAnnotations.get(i);
|
||||
long id = annotation.getId();
|
||||
ids[i] = id;
|
||||
if (annotation instanceof Marker) {
|
||||
((Marker)annotation).hideInfoWindow();
|
||||
}
|
||||
}
|
||||
mNativeMapView.removeAnnotations(ids);
|
||||
mAnnotations.clear();
|
||||
@@ -523,9 +534,6 @@ public class MapView extends FrameLayout implements LocationListener {
|
||||
annotations.add(annotation);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < annotations.size(); i++) {
|
||||
Log.d(TAG, "tapped: " + Long.toString(annotations.get(i).getId()));
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
@@ -731,6 +739,18 @@ public class MapView extends FrameLayout implements LocationListener {
|
||||
return new PointF(point.x * mScreenDensity, point.y * mScreenDensity);
|
||||
}
|
||||
|
||||
public double getTopOffsetPixelsForAnnotationSymbol(@NonNull String symbolName) {
|
||||
return mNativeMapView.getTopOffsetPixelsForAnnotationSymbol(symbolName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Common Screen Density
|
||||
* @return Screen Density
|
||||
*/
|
||||
public float getScreenDensity() {
|
||||
return mScreenDensity;
|
||||
}
|
||||
|
||||
//
|
||||
// Lifecycle events
|
||||
//
|
||||
@@ -1026,32 +1046,104 @@ public class MapView extends FrameLayout implements LocationListener {
|
||||
public boolean onSingleTapUp(MotionEvent e) {
|
||||
// Cancel any animation
|
||||
mNativeMapView.cancelTransitions();
|
||||
|
||||
// Select or deselect point annotations
|
||||
PointF tapPoint = new PointF(e.getX(), e.getY());
|
||||
|
||||
float toleranceWidth = 60 * mScreenDensity;
|
||||
float toleranceHeight = 80 * mScreenDensity;
|
||||
|
||||
PointF tr = new PointF(tapPoint.x + toleranceWidth / 2, tapPoint.y + 2 * toleranceHeight / 3);
|
||||
PointF bl = new PointF(tapPoint.x - toleranceWidth / 2, tapPoint.y - 1 * toleranceHeight / 3);
|
||||
|
||||
LatLng sw = fromScreenLocation(bl);
|
||||
LatLng ne = fromScreenLocation(tr);
|
||||
|
||||
BoundingBox bbox = new BoundingBox(ne, sw);
|
||||
|
||||
List<Annotation> annotations = getAnnotationsInBounds(bbox);
|
||||
|
||||
performClick();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called for single taps after a delay
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||
return false;
|
||||
// Open / Close InfoWindow
|
||||
|
||||
float x = e.getX();
|
||||
float y = e.getY();
|
||||
|
||||
// flip y direction vertically to match core GL
|
||||
y = getHeight() - y;
|
||||
|
||||
PointF tapPoint = new PointF(x, y);
|
||||
|
||||
float toleranceWidth = 40 * mScreenDensity;
|
||||
float toleranceHeight = 60 * mScreenDensity;
|
||||
|
||||
RectF tapRect = new RectF(tapPoint.x - toleranceWidth / 2, tapPoint.y + 2 * toleranceHeight / 3,
|
||||
tapPoint.x + toleranceWidth / 2, tapPoint.y - 1 * toleranceHeight / 3);
|
||||
|
||||
List<LatLng> corners = Arrays.asList(
|
||||
fromScreenLocation(new PointF(tapRect.left, tapRect.bottom)),
|
||||
fromScreenLocation(new PointF(tapRect.left, tapRect.top)),
|
||||
fromScreenLocation(new PointF(tapRect.right, tapRect.top)),
|
||||
fromScreenLocation(new PointF(tapRect.right, tapRect.bottom))
|
||||
);
|
||||
|
||||
BoundingBox tapBounds = BoundingBox.fromLatLngs(corners);
|
||||
|
||||
List<Annotation> nearbyAnnotations = getAnnotationsInBounds(tapBounds);
|
||||
|
||||
long newSelectedAnnotationID = -1;
|
||||
|
||||
if (nearbyAnnotations.size() > 0) {
|
||||
|
||||
// there is at least one nearby annotation; select one
|
||||
//
|
||||
// first, sort for comparison and iteration
|
||||
Collections.sort(nearbyAnnotations);
|
||||
|
||||
if (nearbyAnnotations == mAnnotationsNearLastTap)
|
||||
{
|
||||
// the selection candidates haven't changed; cycle through them
|
||||
if (mSelectedAnnotation != null && (mSelectedAnnotation.getId() == mAnnotationsNearLastTap.get(mAnnotationsNearLastTap.size() - 1).getId()))
|
||||
{
|
||||
// the selected annotation is the last in the set; cycle back to the first
|
||||
// note: this could be the selected annotation if only one in set
|
||||
newSelectedAnnotationID = mAnnotationsNearLastTap.get(0).getId();
|
||||
}
|
||||
else if (mSelectedAnnotation != null)
|
||||
{
|
||||
// otherwise increment the selection through the candidates
|
||||
long currentID = mSelectedAnnotation.getId();
|
||||
long result = mAnnotationsNearLastTap.indexOf(mSelectedAnnotation);
|
||||
newSelectedAnnotationID = mAnnotationsNearLastTap.get((int) result + 1).getId();
|
||||
}
|
||||
else
|
||||
{
|
||||
// no current selection; select the first one
|
||||
newSelectedAnnotationID = mAnnotationsNearLastTap.get(0).getId();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// start tracking a new set of nearby annotations
|
||||
mAnnotationsNearLastTap = nearbyAnnotations;
|
||||
|
||||
// select the first one
|
||||
newSelectedAnnotationID = mAnnotationsNearLastTap.get(0).getId();
|
||||
}
|
||||
|
||||
} else {
|
||||
// there are no nearby annotations; deselect if necessary
|
||||
newSelectedAnnotationID = -1;
|
||||
}
|
||||
|
||||
if (newSelectedAnnotationID >= 0) {
|
||||
|
||||
for (Annotation annotation : mAnnotations) {
|
||||
if (annotation instanceof Marker) {
|
||||
if (annotation.getId() == newSelectedAnnotationID) {
|
||||
if (mSelectedAnnotation == null || annotation.getId() != mSelectedAnnotation.getId()) {
|
||||
selectAnnotation(annotation);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// deselect any selected annotation
|
||||
if (mSelectedAnnotation != null) {
|
||||
deselectAnnotation();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called for a long press
|
||||
@@ -1485,7 +1577,7 @@ public class MapView extends FrameLayout implements LocationListener {
|
||||
|
||||
// Called for events that don't fit the other handlers
|
||||
// such as mouse scroll events, mouse moves, joystick, trackpad
|
||||
@Override @TargetApi(12)
|
||||
@Override
|
||||
public boolean onGenericMotionEvent(MotionEvent event) {
|
||||
// Mouse events
|
||||
//if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // this is not available before API 18
|
||||
@@ -1891,5 +1983,39 @@ public class MapView extends FrameLayout implements LocationListener {
|
||||
mGpsMarker.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (change.equals(MapChange.MapChangeRegionWillChange) || change.equals(MapChange.MapChangeRegionWillChangeAnimated)) {
|
||||
deselectAnnotation();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void selectAnnotation(Annotation annotation) {
|
||||
|
||||
if (annotation == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (annotation == mSelectedAnnotation) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (annotation instanceof Marker) {
|
||||
// Need to deselect any currently selected annotation first
|
||||
deselectAnnotation();
|
||||
|
||||
((Marker)annotation).showInfoWindow();
|
||||
mSelectedAnnotation = annotation;
|
||||
}
|
||||
}
|
||||
|
||||
private void deselectAnnotation() {
|
||||
if (mSelectedAnnotation != null && mSelectedAnnotation instanceof Marker) {
|
||||
Marker marker = (Marker) mSelectedAnnotation;
|
||||
if (marker.isInfoWindowShown()) {
|
||||
marker.hideInfoWindow();
|
||||
mSelectedAnnotation = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.mapbox.mapboxgl.views;
|
||||
import android.graphics.PointF;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.mapbox.mapboxgl.annotations.Annotation;
|
||||
import com.mapbox.mapboxgl.annotations.Marker;
|
||||
import com.mapbox.mapboxgl.annotations.Polygon;
|
||||
import com.mapbox.mapboxgl.annotations.Polyline;
|
||||
@@ -11,8 +10,6 @@ import com.mapbox.mapboxgl.geometry.BoundingBox;
|
||||
import com.mapbox.mapboxgl.geometry.LatLng;
|
||||
import com.mapbox.mapboxgl.geometry.LatLngZoom;
|
||||
import com.mapbox.mapboxgl.geometry.ProjectedMeters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// Class that wraps the native methods for convenience
|
||||
@@ -424,6 +421,10 @@ class NativeMapView {
|
||||
return nativeLatLngForPixel(mNativeMapViewPtr, pixel);
|
||||
}
|
||||
|
||||
public double getTopOffsetPixelsForAnnotationSymbol(String symbolName) {
|
||||
return nativeGetTopOffsetPixelsForAnnotationSymbol(mNativeMapViewPtr, symbolName);
|
||||
}
|
||||
|
||||
//
|
||||
// Callbacks
|
||||
//
|
||||
@@ -606,4 +607,6 @@ class NativeMapView {
|
||||
private native PointF nativePixelForLatLng(long nativeMapViewPtr, LatLng latLng);
|
||||
|
||||
private native LatLng nativeLatLngForPixel(long nativeMapViewPtr, PointF pixel);
|
||||
|
||||
private native double nativeGetTopOffsetPixelsForAnnotationSymbol(long nativeMapViewPtr, String symbolName);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:background="@color/white"
|
||||
android:padding="5dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/infowindow_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="18sp"
|
||||
android:maxEms="17"
|
||||
android:layout_gravity="left"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/infoWindowTitle"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/infowindow_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="14sp"
|
||||
android:maxEms="17"
|
||||
android:text="@string/infoWindowDescription"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/infowindow_subdescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="12sp"
|
||||
android:maxEms="17"
|
||||
android:text="@string/infoWindowAddress"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
<com.mapbox.mapboxgl.annotations.InfoWindowTipView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="10dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="black">#000000</color>
|
||||
</resources>
|
||||
@@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="compassContentDescription">Map compass. Click to reset the map rotation to North.</string>
|
||||
<string name="infoWindowTitle">Title</string>
|
||||
<string name="infoWindowDescription">Description</string>
|
||||
<string name="infoWindowAddress">Address</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user