Merge pull request #3639 from mapbox/release-android-v3.1.0

Android 3.1.0 --> master
This commit is contained in:
Brad Leege
2016-01-20 16:53:58 -05:00
42 changed files with 889 additions and 347 deletions

View File

@@ -10,6 +10,20 @@ import android.view.ViewGroup;
import com.mapbox.mapboxsdk.utils.ApiAccess;
import com.mapbox.mapboxsdk.views.MapView;
/**
* Fragment wrapper around a {@link MapView}.
* <p>
* A Map component in an app. This fragment is the simplest way to place a map in an application.
* It's a wrapper around a view of a map to automatically handle the necessary life cycle needs.
* Being a fragment, this component can be added to an activity's layout or can dynamically be added
* using a FragmentManager.
* </p>
* <p>
* To get a reference to the MapView, use {@link #getMap()}
* </p>
*
* @see #getMap()
*/
public class MapFragment extends Fragment {
//

View File

@@ -5,10 +5,12 @@ import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.views.MapView;
/**
* Annotation is the most general kind of overlay on top of a map,
* from which {@link InfoWindow} and {@link Marker} are derived: it manages
* attachment to a map and identification, but does not require
* Annotation is a overlay on top of a {@link MapView},
* from which {@link Polygon}, {@link Polyline} and {@link Marker} are derived.
* <p>
* it manages attachment to a map and identification, but does not require
* content to be placed at a geographical point.
* </p>
*/
public abstract class Annotation implements Comparable<Annotation> {

View File

@@ -2,6 +2,10 @@ package com.mapbox.mapboxsdk.annotations;
import android.graphics.Bitmap;
/**
* Icon is the visual representation of a {@link Marker} on a {@link com.mapbox.mapboxsdk.views.MapView}.
* @see Marker
*/
public final class Icon {
private Bitmap mBitmap;
private String mId;

View File

@@ -22,6 +22,10 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* Factory for creating {@link Icon} objects.
* @see Icon
*/
public final class IconFactory {
private static final String ICON_ID_PREFIX = "com.mapbox.icons.icon_";

View File

@@ -1,8 +1,8 @@
package com.mapbox.mapboxsdk.annotations;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PointF;
import android.support.annotation.LayoutRes;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -17,32 +17,29 @@ import java.lang.ref.WeakReference;
/**
* <p>
* A tooltip view. This is a UI element placed over a map at a specific geographic
* location.
* InfoWindow is a tooltip shown when a {@link Marker} is tapped.
* </p>
* <p>
* This is a UI element placed over a map at a specific geographic location.
* </p>
*/
public class InfoWindow {
private WeakReference<Marker> mBoundMarker;
private WeakReference<MapView> mMapView;
protected WeakReference<View> mView;
private float mMarkerHeightOffset;
private float mViewWidthOffset;
private PointF mCoordinates;
private boolean mIsVisible;
protected WeakReference<View> mView;
static int mTitleId = 0;
static int mDescriptionId = 0;
static int mSubDescriptionId = 0;
static int mImageId = 0;
@LayoutRes
private int mLayoutRes;
InfoWindow(int layoutResId, MapView mapView) {
mLayoutRes = layoutResId;
View view = LayoutInflater.from(mapView.getContext()).inflate(layoutResId, mapView, false);
if (mTitleId == 0) {
setResIds(mapView.getContext());
}
initialize(view, mapView);
}
@@ -86,7 +83,7 @@ public class InfoWindow {
* This allows to offset the view from the object position.
* @return this infowindow
*/
InfoWindow open(Marker boundMarker, LatLng position, int offsetX, int offsetY) {
InfoWindow open(MapView mapView, Marker boundMarker, LatLng position, int offsetX, int offsetY) {
setBoundMarker(boundMarker);
MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT);
@@ -99,21 +96,21 @@ public class InfoWindow {
mMarkerHeightOffset = -view.getMeasuredHeight() + offsetY;
// Calculate default Android x,y coordinate
mCoordinates = mMapView.get().toScreenLocation(position);
mCoordinates = mapView.toScreenLocation(position);
float x = mCoordinates.x - (view.getMeasuredWidth() / 2) + offsetX;
float y = mCoordinates.y - view.getMeasuredHeight() + offsetY;
if (view instanceof InfoWindowView) {
// only apply repositioning/margin for InfoWindowView
Resources resources = mMapView.get().getContext().getResources();
Resources resources = mapView.getContext().getResources();
// get right/left popup window
float rightSideInfowWindow = x + view.getMeasuredWidth();
float leftSideInfoWindow = x;
// get right/left map view
final float mapRight = mMapView.get().getRight();
final float mapLeft = mMapView.get().getLeft();
final float mapRight = mapView.getRight();
final float mapLeft = mapView.getLeft();
float marginHorizontal = resources.getDimension(R.dimen.infowindow_margin);
float tipViewOffset = resources.getDimension(R.dimen.infowindow_tipview_width) / 2;
@@ -164,7 +161,7 @@ public class InfoWindow {
mViewWidthOffset = x - mCoordinates.x - offsetX;
close(); //if it was already opened
mMapView.get().addView(view, lp);
mapView.addView(view, lp);
mIsVisible = true;
}
return this;
@@ -194,25 +191,17 @@ public class InfoWindow {
*
* @param overlayItem the tapped overlay item
*/
void adaptDefaultMarker(Marker overlayItem) {
void adaptDefaultMarker(Marker overlayItem, MapView mapView) {
View view = mView.get();
if (view != null) {
String title = overlayItem.getTitle();
((TextView) view.findViewById(mTitleId /*R.id.title*/)).setText(title);
String snippet = overlayItem.getSnippet();
((TextView) view.findViewById(mDescriptionId /*R.id.description*/)).setText(snippet);
if (view == null) {
view = LayoutInflater.from(mapView.getContext()).inflate(mLayoutRes, mapView, false);
initialize(view, mapView);
}
/*
//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);
}
*/
mMapView = new WeakReference<>(mapView);
String title = overlayItem.getTitle();
((TextView) view.findViewById(R.id.infowindow_title)).setText(title);
String snippet = overlayItem.getSnippet();
((TextView) view.findViewById(R.id.infowindow_description)).setText(snippet);
}
private void onClose() {
@@ -231,22 +220,6 @@ public class InfoWindow {
return mBoundMarker.get();
}
/**
* Given a context, set the resource ids for the layout
* of the InfoWindow.
*
* @param context the apps 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);
}
public void update() {
MapView mapView = mMapView.get();
Marker marker = mBoundMarker.get();

View File

@@ -1,5 +1,6 @@
package com.mapbox.mapboxsdk.annotations;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
@@ -8,9 +9,10 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.views.MapView;
/**
* A marker is a map overlay that shows an icon image at a specific
* geographical location and can be associated with a {@link InfoWindow}
* that is shown when the marker is tapped.
* Marker is an annotation that shows an icon image at a geographical location.
* </p>
* An {@link InfoWindow} can be shown when a Marker is pressed
* <p>
*/
public final class Marker extends Annotation {
@@ -53,6 +55,8 @@ public final class Marker extends Annotation {
/**
* Do not use this method. Used internally by the SDK.
*
* @return boolean State of a InfoWindow
*/
public boolean isInfoWindowShown() {
return infoWindowShown;
@@ -68,6 +72,8 @@ public final class Marker extends Annotation {
/**
* Do not use this method. Used internally by the SDK.
*
* @param icon The icon to be used as Marker image
*/
public void setIcon(@Nullable Icon icon) {
this.icon = icon;
@@ -83,29 +89,29 @@ public final class Marker extends Annotation {
/**
* Do not use this method. Used internally by the SDK.
*
* @param mapView The MapView to show the InfoWindow on.
* @return infoWindow The infoWindow to show
*/
public InfoWindow showInfoWindow() {
if (getMapView() == null) {
return null;
}
public InfoWindow showInfoWindow(@NonNull MapView mapView) {
setMapView(mapView);
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);
showInfoWindow(infoWindow, mapView);
return infoWindow;
}
}
getInfoWindow().adaptDefaultMarker(this);
return showInfoWindow(getInfoWindow());
getInfoWindow().adaptDefaultMarker(this, mapView);
return showInfoWindow(getInfoWindow(), mapView);
}
private InfoWindow showInfoWindow(InfoWindow iw) {
iw.open(this, getPosition(), 0, topOffsetPixels);
private InfoWindow showInfoWindow(InfoWindow iw, MapView mapView) {
iw.open(mapView, this, getPosition(), 0, topOffsetPixels);
infoWindowShown = true;
return iw;
}
@@ -129,6 +135,8 @@ public final class Marker extends Annotation {
/**
* Do not use this method. Used internally by the SDK.
*
* @param topOffsetPixels the pixels to have as offset
*/
public void setTopOffsetPixels(int topOffsetPixels) {
this.topOffsetPixels = topOffsetPixels;

View File

@@ -10,9 +10,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
/**
* <p>
* A builder object for the options configuration {@link com.mapbox.mapboxsdk.annotations.Marker} and
* {@link com.mapbox.mapboxsdk.annotations.InfoWindow}
* instances on maps.
* Builder for composing {@link com.mapbox.mapboxsdk.annotations.Marker} objects.
* </p>
*
* <h3>Example</h3>
@@ -70,6 +68,8 @@ public final class MarkerOptions implements Parcelable {
/**
* Do not use this method. Used internally by the SDK.
*
* @return Marker The build marker
*/
public Marker getMarker() {
return marker;

View File

@@ -5,6 +5,9 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import java.util.ArrayList;
import java.util.List;
/**
* Multipoint is an abstract annotation for combining geographical locations.
*/
public abstract class MultiPoint extends Annotation {
private List<LatLng> points;

View File

@@ -9,6 +9,9 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import java.util.ArrayList;
import java.util.List;
/**
* Builder for composing {@link Polygon} objects.
*/
public final class PolygonOptions implements Parcelable {
public static final Parcelable.Creator<PolygonOptions> CREATOR
@@ -96,6 +99,8 @@ public final class PolygonOptions implements Parcelable {
/**
* Do not use this method. Used internally by the SDK.
*
* @return Polygon the Polygon to return
*/
public Polygon getPolygon() {
return polygon;

View File

@@ -8,6 +8,9 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import java.util.ArrayList;
import java.util.List;
/**
* Builder for composing {@link Polyline} objects.
*/
public final class PolylineOptions implements Parcelable {
@@ -83,6 +86,7 @@ public final class PolylineOptions implements Parcelable {
* Sets the color of the polyline.
*
* @param color - the color in ARGB format
* @return PolyLineOptions The builder used to build a Polyline
*/
public PolylineOptions color(int color) {
polyline.setColor(color);
@@ -95,6 +99,7 @@ public final class PolylineOptions implements Parcelable {
/**
* Do not use this method. Used internally by the SDK.
* @return PolyLine The polyline build by this class.
*/
public Polyline getPolyline() {
return polyline;

View File

@@ -9,7 +9,7 @@ import java.util.List;
/**
* A rectangular geographical area defined in latitude and longitude units.
*/
public final class BoundingBox implements Parcelable, Serializable {
public final class BoundingBox implements Parcelable {
private final double mLatNorth;
private final double mLatSouth;

View File

@@ -1,41 +1,52 @@
package com.mapbox.mapboxsdk.geometry;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
/**
* Implementation of iOS MGLCoordinateBounds
* A rectangular geograpical region defined by a south west {@link LatLng} and a north east {@link LatLng}.
*/
public class CoordinateBounds {
public class CoordinateBounds implements Parcelable {
private LatLng southWest;
private LatLng northEast;
private LatLng mSouthWest;
private LatLng mNorthEast;
public CoordinateBounds(LatLng southWest, LatLng northEast) {
this.southWest = southWest;
this.northEast = northEast;
public CoordinateBounds(@NonNull Parcel in) {
mSouthWest = in.readParcelable(LatLng.class.getClassLoader());
mNorthEast = in.readParcelable(LatLng.class.getClassLoader());
}
public CoordinateBounds(@NonNull LatLng southWest, @NonNull LatLng northEast) {
mSouthWest = southWest;
mNorthEast = northEast;
}
@NonNull
public LatLng getSouthWest() {
return southWest;
return mSouthWest;
}
public void setSouthWest(LatLng southWest) {
this.southWest = southWest;
public void setSouthWest(@NonNull LatLng mSouthWest) {
this.mSouthWest = mSouthWest;
}
@NonNull
public LatLng getNorthEast() {
return northEast;
return mNorthEast;
}
public void setNorthEast(LatLng northEast) {
this.northEast = northEast;
public void setNorthEast(@NonNull LatLng mNorthEast) {
this.mNorthEast = mNorthEast;
}
@Override
public int hashCode() {
int result;
long temp;
temp = southWest.hashCode();
temp = mSouthWest.hashCode();
result = (int) (temp ^ (temp >>> 32));
temp = northEast.hashCode();
temp = mNorthEast.hashCode();
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
@@ -53,6 +64,30 @@ public class CoordinateBounds {
@Override
public String toString() {
return "CoordinateBounds [northEast[" + getNorthEast() + "], southWest[]" + getSouthWest() + "]";
return "CoordinateBounds [mNorthEast[" + getNorthEast() + "], mSouthWest[]" + getSouthWest() + "]";
}
public static final Parcelable.Creator<CoordinateBounds> CREATOR =
new Parcelable.Creator<CoordinateBounds>() {
@Override
public CoordinateBounds createFromParcel(Parcel in) {
return new CoordinateBounds(in);
}
@Override
public CoordinateBounds[] newArray(int size) {
return new CoordinateBounds[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int arg1) {
out.writeParcelable(mSouthWest, arg1);
out.writeParcelable(mNorthEast, arg1);
}
}

View File

@@ -1,30 +1,64 @@
package com.mapbox.mapboxsdk.geometry;
/**
* Implementation of iOS MKCoordinateRegion
*/
public class CoordinateRegion {
private LatLng center;
private CoordinateSpan span;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
public CoordinateRegion(final LatLng center, final CoordinateSpan span) {
this.center = center;
this.span = span;
/**
* A geographical region defined by a {@link LatLng} and a {@link CoordinateSpan}.
*/
public class CoordinateRegion implements Parcelable{
private LatLng mCenter;
private CoordinateSpan mSpan;
public CoordinateRegion(@NonNull Parcel in){
mCenter = in.readParcelable(LatLng.class.getClassLoader());
mSpan = in.readParcelable(CoordinateSpan.class.getClassLoader());
}
public CoordinateRegion(@NonNull LatLng center, @NonNull CoordinateSpan span) {
mCenter = center;
mSpan = span;
}
public LatLng getCenter() {
return center;
return mCenter;
}
public void setCenter(final LatLng center) {
this.center = center;
public void setCenter(@NonNull LatLng center) {
mCenter = center;
}
public CoordinateSpan getSpan() {
return span;
return mSpan;
}
public void setSpan(final CoordinateSpan span) {
this.span = span;
public void setSpan(@NonNull CoordinateSpan span) {
this.mSpan = span;
}
public static final Parcelable.Creator<CoordinateRegion> CREATOR =
new Parcelable.Creator<CoordinateRegion>() {
@Override
public CoordinateRegion createFromParcel(Parcel in) {
return new CoordinateRegion(in);
}
@Override
public CoordinateRegion[] newArray(int size) {
return new CoordinateRegion[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int arg1) {
out.writeParcelable(mCenter, arg1);
out.writeParcelable(mSpan, arg1);
}
}

View File

@@ -1,32 +1,41 @@
package com.mapbox.mapboxsdk.geometry;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
/**
* Implementation of iOS MKCoordinateSpan
* A geographical span defined by its latitude and longitude span.
*/
public class CoordinateSpan {
public class CoordinateSpan implements Parcelable {
private double latitudeSpan;
private double longitudeSpan;
private double mLatitudeSpan;
private double mLongitudeSpan;
public CoordinateSpan(final double latitudeSpan, final double longitudeSpan) {
this.latitudeSpan = latitudeSpan;
this.longitudeSpan = longitudeSpan;
public CoordinateSpan(@NonNull Parcel in){
mLatitudeSpan = in.readDouble();
mLongitudeSpan = in.readDouble();
}
public CoordinateSpan(double latitudeSpan, double longitudeSpan) {
mLatitudeSpan = latitudeSpan;
mLongitudeSpan = longitudeSpan;
}
public double getLatitudeSpan() {
return latitudeSpan;
return mLatitudeSpan;
}
public void setLatitudeSpan(final double latitudeSpan) {
this.latitudeSpan = latitudeSpan;
public void setLatitudeSpan(double latitudeSpan) {
mLatitudeSpan = latitudeSpan;
}
public double getLongitudeSpan() {
return longitudeSpan;
return mLongitudeSpan;
}
public void setLongitudeSpan(final double longitudeSpan) {
this.longitudeSpan = longitudeSpan;
public void setLongitudeSpan(double longitudeSpan) {
mLongitudeSpan = longitudeSpan;
}
@Override
@@ -34,10 +43,33 @@ public class CoordinateSpan {
if (this == o) return true;
if (o instanceof CoordinateSpan) {
CoordinateSpan other = (CoordinateSpan) o;
return longitudeSpan == other.getLongitudeSpan()
&& latitudeSpan == other.getLatitudeSpan();
return mLongitudeSpan == other.getLongitudeSpan()
&& mLatitudeSpan == other.getLatitudeSpan();
}
return false;
}
}
public static final Parcelable.Creator<CoordinateSpan> CREATOR =
new Parcelable.Creator<CoordinateSpan>() {
@Override
public CoordinateSpan createFromParcel(Parcel in) {
return new CoordinateSpan(in);
}
@Override
public CoordinateSpan[] newArray(int size) {
return new CoordinateSpan[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int arg1) {
out.writeDouble(mLatitudeSpan);
out.writeDouble(mLongitudeSpan);
}
}

View File

@@ -1,7 +1,7 @@
package com.mapbox.mapboxsdk.geometry;
/**
* A Latitude, Longitude point.
* Describes a latitude, longitude point.
*/
public interface ILatLng {
double getLatitude();

View File

@@ -1,5 +1,8 @@
package com.mapbox.mapboxsdk.geometry;
/**
* Describes a projection in Mercator meters.
*/
public interface IProjectedMeters {
double getNorthing();

View File

@@ -10,9 +10,10 @@ import com.mapbox.mapboxsdk.constants.MathConstants;
import java.io.Serializable;
/**
* A geographical location which contains a single latitude, longitude pair, with
* optional altitude.
* <p>
* This class is container for a single latitude, longitude pair, with
* optional altitude. Latitude and longitude are expressed as decimal degrees
* Latitude and longitude are expressed as decimal degrees
* in the WGS84 datum. By default, altitude is 0.0, or sea level.
* </p>
* <p>
@@ -20,7 +21,7 @@ import java.io.Serializable;
* data automatically, so all data enters in the WGS84 datum.
* </p>
*/
public class LatLng implements ILatLng, Parcelable, Serializable {
public class LatLng implements ILatLng, Parcelable {
public static final Parcelable.Creator<LatLng> CREATOR = new Parcelable.Creator<LatLng>() {
public LatLng createFromParcel(Parcel in) {
@@ -129,7 +130,6 @@ public class LatLng implements ILatLng, Parcelable, Serializable {
LatLng latLng = (LatLng) o;
return Double.compare(latLng.altitude, altitude) == 0 && Double.compare(latLng.latitude, latitude) == 0 && Double.compare(latLng.longitude, longitude) == 0;
}
@Override
@@ -168,6 +168,10 @@ public class LatLng implements ILatLng, Parcelable, Serializable {
* @return distance in meters
*/
public double distanceTo(LatLng other) {
if(latitude == other.latitude && longitude == other.longitude){
// return 0.0 to avoid a NaN
return 0.0;
}
final double a1 = MathConstants.DEG2RAD * this.latitude;
final double a2 = MathConstants.DEG2RAD * this.longitude;

View File

@@ -5,7 +5,10 @@ import android.os.Parcelable;
import java.io.Serializable;
public class LatLngZoom extends LatLng implements Parcelable, Serializable {
/**
* A geographical location which contains a {@link LatLng}, zoom pair.
*/
public class LatLngZoom extends LatLng implements Parcelable {
public static final Parcelable.Creator<LatLngZoom> CREATOR = new Parcelable.Creator<LatLngZoom>() {
public LatLngZoom createFromParcel(Parcel in) {

View File

@@ -6,12 +6,14 @@ import android.os.Parcelable;
import java.io.Serializable;
/**
* ProjectedMeters is an internal representation of longitude, latitude points that
* have been projected into Mapbox GL's Mercator projection. Instead of decimal
* ProjectedMeters is a projection of longitude, latitude points in Mercator meters.
* <p>
* these have been projected into Mapbox GL's Mercator projection. Instead of decimal
* degrees, it uses Mercator meters (which are notably not equivalent to SI meters)
* except at the equator.
* </p>
*/
public class ProjectedMeters implements IProjectedMeters, Parcelable, Serializable {
public class ProjectedMeters implements IProjectedMeters, Parcelable {
public static final Creator<ProjectedMeters> CREATOR = new Creator<ProjectedMeters>() {
public ProjectedMeters createFromParcel(Parcel in) {

View File

@@ -139,6 +139,7 @@ public final class MapView extends FrameLayout {
private static final String STATE_DEFAULT_TRANSITION_DURATION = "defaultTransitionDuration";
private static final String STATE_MY_LOCATION_ENABLED = "myLocationEnabled";
private static final String STATE_MY_LOCATION_TRACKING_MODE = "myLocationTracking";
private static final String STATE_MY_BEARING_TRACKING_MODE = "myBearingTracking";
private static final String STATE_COMPASS_ENABLED = "compassEnabled";
private static final String STATE_COMPASS_GRAVITY = "compassGravity";
private static final String STATE_COMPASS_MARGIN_LEFT = "compassMarginLeft";
@@ -804,7 +805,7 @@ public final class MapView extends FrameLayout {
mZoomButtonsController.setOnZoomListener(new OnZoomListener());
// Check current connection status
ConnectivityManager connectivityManager = (ConnectivityManager) context
ConnectivityManager connectivityManager = (ConnectivityManager) context.getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
boolean isConnected = (activeNetwork != null) && activeNetwork.isConnectedOrConnecting();
@@ -973,6 +974,8 @@ public final class MapView extends FrameLayout {
//noinspection ResourceType
setMyLocationTrackingMode(savedInstanceState.getInt(STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
//noinspection ResourceType
setMyBearingTrackingMode(savedInstanceState.getInt(STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE));
}
// Force a check for an access token
@@ -1025,6 +1028,7 @@ public final class MapView extends FrameLayout {
outState.putLong(STATE_DEFAULT_TRANSITION_DURATION, mNativeMapView.getDefaultTransitionDuration());
outState.putBoolean(STATE_MY_LOCATION_ENABLED, isMyLocationEnabled());
outState.putInt(STATE_MY_LOCATION_TRACKING_MODE, mUserLocationView.getMyLocationTrackingMode());
outState.putInt(STATE_MY_BEARING_TRACKING_MODE, mUserLocationView.getMyBearingTrackingMode());
// Compass
LayoutParams compassParams = (LayoutParams) mCompassView.getLayoutParams();
@@ -2694,8 +2698,9 @@ public final class MapView extends FrameLayout {
}
if (!handledDefaultClick) {
// default behaviour show InfoWindow
mInfoWindows.add(marker.showInfoWindow());
if (isInfoWindowValidForMarker(marker)) {
mInfoWindows.add(marker.showInfoWindow(this));
}
}
mSelectedMarkers.add(marker);
@@ -2736,6 +2741,10 @@ public final class MapView extends FrameLayout {
mSelectedMarkers.remove(marker);
}
private boolean isInfoWindowValidForMarker(@NonNull Marker marker) {
return !TextUtils.isEmpty(marker.getTitle()) || !TextUtils.isEmpty(marker.getSnippet());
}
//
// Mapbox Core GL Camera
//
@@ -2873,10 +2882,8 @@ public final class MapView extends FrameLayout {
for (Marker marker : mSelectedMarkers) {
if (marker.isInfoWindowShown()) {
Marker temp = marker;
temp.hideInfoWindow();
temp.showInfoWindow();
marker = temp;
marker.hideInfoWindow();
marker.showInfoWindow(this);
}
}
}
@@ -3173,9 +3180,9 @@ public final class MapView extends FrameLayout {
// Open / Close InfoWindow
PointF tapPoint = new PointF(e.getX(), e.getY());
final float toleranceSides = 30 * mScreenDensity;
final float toleranceTop = 40 * mScreenDensity;
final float toleranceBottom = 10 * mScreenDensity;
final float toleranceSides = 15 * mScreenDensity;
final float toleranceTop = 20 * mScreenDensity;
final float toleranceBottom = 5 * mScreenDensity;
RectF tapRect = new RectF(tapPoint.x - toleranceSides, tapPoint.y + toleranceTop,
tapPoint.x + toleranceSides, tapPoint.y - toleranceBottom);
@@ -3188,52 +3195,27 @@ public final class MapView extends FrameLayout {
);
BoundingBox tapBounds = BoundingBox.fromLatLngs(corners);
List<Marker> nearbyMarkers = getMarkersInBounds(tapBounds);
long newSelectedMarkerId = -1;
long newSelectedMarkerId;
if (nearbyMarkers.size() > 0) {
// there is at least one nearby marker; select one
//
// first, sort for comparison and iteration
if (nearbyMarkers!=null && nearbyMarkers.size() > 0) {
Collections.sort(nearbyMarkers);
if (nearbyMarkers == mMarkersNearLastTap) {
// TODO: We still need to adapt this logic to the new mSelectedMarkers list,
// though the basic functionality is there.
// the selection candidates haven't changed; cycle through them
// if (mSelectedMarker != null
// && (mSelectedMarker.getId() == mMarkersNearLastTap.get(mMarkersNearLastTap.size() - 1).getId())) {
// // the selected marker is the last in the set; cycle back to the first
// // note: this could be the selected marker if only one in set
// newSelectedMarkerId = mMarkersNearLastTap.get(0).getId();
// } else if (mSelectedMarker != null) {
// // otherwise increment the selection through the candidates
// long result = mMarkersNearLastTap.indexOf(mSelectedMarker);
// newSelectedMarkerId = mMarkersNearLastTap.get((int) result + 1).getId();
// } else {
// no current selection; select the first one
newSelectedMarkerId = mMarkersNearLastTap.get(0).getId();
// }
} else {
// start tracking a new set of nearby markers
mMarkersNearLastTap = nearbyMarkers;
// select the first one
newSelectedMarkerId = mMarkersNearLastTap.get(0).getId();
for (Marker nearbyMarker : nearbyMarkers) {
boolean found = false;
for (Marker selectedMarker : mSelectedMarkers) {
if(selectedMarker.equals(nearbyMarker)){
found = true;
}
}
if(!found){
newSelectedMarkerId = nearbyMarker.getId();
break;
}
}
} else {
// there are no nearby markers; deselect if necessary
newSelectedMarkerId = -1;
mMarkersNearLastTap = nearbyMarkers;
}
if (newSelectedMarkerId >= 0) {
int count = mAnnotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.get(i);
@@ -3246,7 +3228,6 @@ public final class MapView extends FrameLayout {
}
}
}
} else {
// deselect any selected marker
deselectMarkers();

View File

@@ -34,11 +34,13 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationListener;
import com.mapbox.mapboxsdk.location.LocationServices;
import java.lang.ref.WeakReference;
/**
* This view shows the user's location, as determined from GPS, on the map
* as a dot annotation.
*/
final class UserLocationView extends View implements LocationListener {
final class UserLocationView extends View {
private MapView mMapView;
@@ -85,6 +87,7 @@ final class UserLocationView extends View implements LocationListener {
private boolean mPaused = false;
private Location mUserLocation;
private UserLocationListener mUserLocationListener;
MapView.OnMyLocationChangeListener mOnMyLocationChangeListener;
@@ -377,14 +380,18 @@ final class UserLocationView extends View implements LocationListener {
setLocation(lastLocation);
}
if(mUserLocationListener==null){
mUserLocationListener = new UserLocationListener(this);
}
// Register for Location Updates
locationServices.addLocationListener(this);
locationServices.addLocationListener(mUserLocationListener);
} else {
// Disable location and user dot
setLocation(null);
// Deregister for Location Updates
locationServices.removeLocationListener(this);
locationServices.removeLocationListener(mUserLocationListener);
}
locationServices.toggleGPS(enableGps);
@@ -498,17 +505,27 @@ final class UserLocationView extends View implements LocationListener {
}
}
/**
* Callback method for receiving location updates from LocationServices.
*
* @param location The new Location data
*/
@Override
public void onLocationChanged(Location location) {
if (mPaused) {
return;
private static class UserLocationListener implements LocationListener{
private WeakReference<UserLocationView> mUserLocationView;
public UserLocationListener(UserLocationView userLocationView) {
mUserLocationView = new WeakReference<>(userLocationView);
}
/**
* Callback method for receiving location updates from LocationServices.
*
* @param location The new Location data
*/
@Override
public void onLocationChanged(Location location) {
UserLocationView locationView = mUserLocationView.get();
if(locationView!=null && !locationView.isPaused()){
locationView.setLocation(location);
}
}
setLocation(location);
}
private boolean isStale(Location location) {
@@ -751,4 +768,8 @@ final class UserLocationView extends View implements LocationListener {
}
}
public boolean isPaused(){
return mPaused;
}
}