Merge remote-tracking branch 'origin/release-android-v4.1.0'
@@ -2,6 +2,27 @@
|
||||
|
||||
Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started.
|
||||
|
||||
## 4.1.0
|
||||
|
||||
Mapbox Android 4.1.0 builds off our ambitious 4.0.0 version with 3 major new features being released.
|
||||
|
||||
* View Based Annotations ([#3276](https://github.com/mapbox/mapbox-gl-native/issues/3276))
|
||||
* UserLocationView Refactor ([#4396](https://github.com/mapbox/mapbox-gl-native/issues/4396))
|
||||
* MapboxAccountManager ([#5004](https://github.com/mapbox/mapbox-gl-native/issues/5004))
|
||||
|
||||
## 4.1.0-beta.3
|
||||
|
||||
* New samples:
|
||||
* [Location picker](https://github.com/mapbox/mapbox-gl-native/pull/5391)
|
||||
* [Animate and rotate multiple markers](https://github.com/mapbox/mapbox-gl-native/issues/5299)
|
||||
* [Scaling marker activity](https://github.com/mapbox/mapbox-gl-native/issues/5409)
|
||||
* Marker improvements:
|
||||
* [Expose MarkerView alpha](https://github.com/mapbox/mapbox-gl-native/pull/5329)
|
||||
* [Icon should be optional for MarkerView](https://github.com/mapbox/mapbox-gl-native/pull/5328)
|
||||
* [Expose an API to enable selection/deselection of markers on a map tap](https://github.com/mapbox/mapbox-gl-native/pull/5312)
|
||||
* [Bring selected MarkerView to the front](https://github.com/mapbox/mapbox-gl-native/pull/5294)
|
||||
* [Make gesture focal point configurable](https://github.com/mapbox/mapbox-gl-native/pull/5332)
|
||||
|
||||
## 4.1.0-beta.2
|
||||
|
||||
* Dynamically Update InfoWindow ([#5237](https://github.com/mapbox/mapbox-gl-native/issues/5237))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.mapbox.mapboxsdk
|
||||
VERSION_NAME=4.1.0-SNAPSHOT
|
||||
VERSION_NAME=4.2.0-SNAPSHOT
|
||||
|
||||
POM_DESCRIPTION=Mapbox GL Android SDK
|
||||
POM_URL=https://github.com/mapbox/mapbox-gl-native
|
||||
@@ -17,6 +17,6 @@ ANDROID_BUILD_TARGET_SDK_VERSION=23
|
||||
ANDROID_BUILD_TOOLS_VERSION=23.0.3
|
||||
ANDROID_BUILD_SDK_VERSION=23
|
||||
|
||||
POM_NAME=Mapbox GL Android SDK
|
||||
POM_NAME=Mapbox Android SDK
|
||||
POM_ARTIFACT_ID=mapbox-android-sdk
|
||||
POM_PACKAGING=aar
|
||||
|
||||
@@ -39,6 +39,22 @@ public abstract class BaseMarkerOptions<U extends Marker, T extends BaseMarkerOp
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public T setIcon(Icon icon) {
|
||||
return icon(icon);
|
||||
}
|
||||
|
||||
public T setPosition(LatLng position) {
|
||||
return position(position);
|
||||
}
|
||||
|
||||
public T setSnippet(String snippet) {
|
||||
return snippet(snippet);
|
||||
}
|
||||
|
||||
public T setTitle(String title) {
|
||||
return title(title);
|
||||
}
|
||||
|
||||
public abstract T getThis();
|
||||
|
||||
public abstract U getMarker();
|
||||
|
||||
@@ -29,6 +29,7 @@ public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends Base
|
||||
protected float rotation;
|
||||
protected boolean visible = true;
|
||||
protected boolean selected;
|
||||
protected float alpha = 1.0f;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
@@ -132,13 +133,24 @@ public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends Base
|
||||
* Set the visibility state of the MarkerView.
|
||||
*
|
||||
* @param visible the visible state
|
||||
* @return the object for which the method was calleds
|
||||
* @return the object for which the method was called
|
||||
*/
|
||||
public T visible(boolean visible) {
|
||||
this.visible = visible;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alpha of the MarkerView.
|
||||
*
|
||||
* @param alpha the alpha value
|
||||
* @return the object for which the method was called
|
||||
*/
|
||||
public T alpha(float alpha) {
|
||||
this.alpha = alpha;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the geographical location of the MarkerView.
|
||||
*
|
||||
@@ -238,6 +250,15 @@ public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends Base
|
||||
return visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the alpha of the MarkerView.
|
||||
*
|
||||
* @return the alpha value
|
||||
*/
|
||||
public float getAlpha() {
|
||||
return alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of the object for which this method was called.
|
||||
*
|
||||
|
||||
@@ -33,6 +33,7 @@ public final class IconFactory {
|
||||
private Context mContext;
|
||||
private static IconFactory sInstance;
|
||||
private Icon mDefaultMarker;
|
||||
private Icon mDefaultMarkerView;
|
||||
private BitmapFactory.Options mOptions;
|
||||
|
||||
private int mNextId = 0;
|
||||
@@ -121,6 +122,13 @@ public final class IconFactory {
|
||||
return mDefaultMarker;
|
||||
}
|
||||
|
||||
public Icon defaultMarkerView() {
|
||||
if (mDefaultMarkerView == null) {
|
||||
mDefaultMarkerView = fromResource(R.drawable.default_markerview);
|
||||
}
|
||||
return mDefaultMarkerView;
|
||||
}
|
||||
|
||||
private Icon fromInputStream(@NonNull InputStream is) {
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(is, null, mOptions);
|
||||
return fromBitmap(bitmap);
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.annotations;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PointF;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -222,9 +223,22 @@ public class InfoWindow {
|
||||
}
|
||||
mMapboxMap = new WeakReference<>(mapboxMap);
|
||||
String title = overlayItem.getTitle();
|
||||
((TextView) view.findViewById(R.id.infowindow_title)).setText(title);
|
||||
TextView titleTextView = ((TextView) view.findViewById(R.id.infowindow_title));
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
titleTextView.setText(title);
|
||||
titleTextView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
titleTextView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
String snippet = overlayItem.getSnippet();
|
||||
((TextView) view.findViewById(R.id.infowindow_description)).setText(snippet);
|
||||
TextView snippetTextView = ((TextView) view.findViewById(R.id.infowindow_description));
|
||||
if (!TextUtils.isEmpty(snippet)) {
|
||||
snippetTextView.setText(snippet);
|
||||
snippetTextView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
snippetTextView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
InfoWindow setBoundMarker(Marker boundMarker) {
|
||||
@@ -245,11 +259,20 @@ public class InfoWindow {
|
||||
View view = mView.get();
|
||||
if (mapboxMap != null && marker != null && view != null) {
|
||||
mCoordinates = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
|
||||
view.setX(mCoordinates.x + mViewWidthOffset - mMarkerWidthOffset);
|
||||
|
||||
if (view instanceof InfoWindowView) {
|
||||
view.setX(mCoordinates.x + mViewWidthOffset - mMarkerWidthOffset);
|
||||
} else {
|
||||
view.setX(mCoordinates.x - (view.getMeasuredWidth() / 2) - mMarkerWidthOffset);
|
||||
}
|
||||
view.setY(mCoordinates.y + mMarkerHeightOffset);
|
||||
}
|
||||
}
|
||||
|
||||
public View getView() {
|
||||
return mView != null ? mView.get() : null;
|
||||
}
|
||||
|
||||
boolean isVisible() {
|
||||
return mIsVisible;
|
||||
}
|
||||
|
||||
@@ -117,6 +117,11 @@ public class Marker extends Annotation {
|
||||
refreshInfoWindowContent();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InfoWindow getInfoWindow() {
|
||||
return infoWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update only for default Marker's InfoWindow content for Title and Snippet
|
||||
*/
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package com.mapbox.mapboxsdk.annotations;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PointF;
|
||||
import android.support.annotation.FloatRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.View;
|
||||
import android.view.animation.AnimationUtils;
|
||||
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.utils.AnimatorUtils;
|
||||
|
||||
/**
|
||||
* MarkerView is an annotation that shows an View at a geographical location.
|
||||
@@ -26,8 +31,8 @@ public class MarkerView extends Marker {
|
||||
private float anchorU;
|
||||
private float anchorV;
|
||||
|
||||
private float offsetX;
|
||||
private float offsetY;
|
||||
private float offsetX = -1;
|
||||
private float offsetY = -1;
|
||||
|
||||
private float infoWindowAnchorU;
|
||||
private float infoWindowAnchorV;
|
||||
@@ -81,6 +86,7 @@ public class MarkerView extends Marker {
|
||||
public void setAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
|
||||
this.anchorU = u;
|
||||
this.anchorV = v;
|
||||
setOffset(-1, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,26 +108,16 @@ public class MarkerView extends Marker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to set the horizontal calculated offset.
|
||||
* Internal method to set the calculated offset.
|
||||
* <p>
|
||||
* These are calculated based on the View bounds and the provided anchor.
|
||||
* </p>
|
||||
*
|
||||
* @param x the x-value of the offset
|
||||
*/
|
||||
void setOffsetX(float x) {
|
||||
offsetX = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to set the vertical calculated offset.
|
||||
* <p>
|
||||
* These are calculated based on the View bounds and the provided anchor.
|
||||
* </p>
|
||||
*
|
||||
* @param y the y-value of the offset
|
||||
*/
|
||||
void setOffsetY(float y) {
|
||||
void setOffset(float x, float y) {
|
||||
offsetX = x;
|
||||
offsetY = y;
|
||||
}
|
||||
|
||||
@@ -279,7 +275,7 @@ public class MarkerView extends Marker {
|
||||
*
|
||||
* @param alpha the alpha value to animate to
|
||||
*/
|
||||
public void setAlpha(@FloatRange(from=0.0, to=255.0)float alpha) {
|
||||
public void setAlpha(@FloatRange(from = 0.0, to = 255.0) float alpha) {
|
||||
this.alpha = alpha;
|
||||
if (markerViewManager != null) {
|
||||
markerViewManager.animateAlpha(this, alpha);
|
||||
@@ -336,6 +332,12 @@ public class MarkerView extends Marker {
|
||||
@Override
|
||||
public void setMapboxMap(MapboxMap mapboxMap) {
|
||||
super.setMapboxMap(mapboxMap);
|
||||
|
||||
if(isFlat()) {
|
||||
// initial tilt value if MapboxMap is started with a tilt attribute
|
||||
tiltValue = (float) mapboxMap.getCameraPosition().tilt;
|
||||
}
|
||||
|
||||
markerViewManager = mapboxMap.getMarkerViewManager();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ import android.graphics.PointF;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.Pools;
|
||||
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;
|
||||
@@ -111,20 +111,20 @@ public class MarkerViewManager {
|
||||
* </p>
|
||||
*/
|
||||
public void update() {
|
||||
View convertView;
|
||||
for (MarkerView marker : markerViewMap.keySet()) {
|
||||
convertView = markerViewMap.get(marker);
|
||||
for (final MarkerView marker : markerViewMap.keySet()) {
|
||||
final View convertView = markerViewMap.get(marker);
|
||||
if (convertView != null) {
|
||||
PointF point = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
|
||||
int x = (int) (marker.getAnchorU() * convertView.getMeasuredWidth());
|
||||
int y = (int) (marker.getAnchorV() * convertView.getMeasuredHeight());
|
||||
if (marker.getOffsetX() == -1) {
|
||||
int x = (int) (marker.getAnchorU() * convertView.getMeasuredWidth());
|
||||
int y = (int) (marker.getAnchorV() * convertView.getMeasuredHeight());
|
||||
marker.setOffset(x, y);
|
||||
}
|
||||
|
||||
marker.setOffsetX(x);
|
||||
marker.setOffsetY(y);
|
||||
|
||||
convertView.setX(point.x - x);
|
||||
convertView.setY(point.y - y);
|
||||
convertView.setX(point.x - marker.getOffsetX());
|
||||
convertView.setY(point.y - marker.getOffsetY());
|
||||
|
||||
// animate visibility
|
||||
if (marker.isVisible() && convertView.getVisibility() == View.GONE) {
|
||||
convertView.animate().cancel();
|
||||
convertView.setAlpha(0);
|
||||
@@ -200,9 +200,10 @@ public class MarkerViewManager {
|
||||
* <p>
|
||||
* The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onSelect(MarkerView, View, boolean)} will be called to execute an animation.
|
||||
* </p>
|
||||
* @param marker the MarkerView object to select
|
||||
*
|
||||
* @param marker the MarkerView object to select
|
||||
* @param convertView the View presentation of the MarkerView
|
||||
* @param adapter the adapter used to adapt the marker to the convertView
|
||||
* @param adapter the adapter used to adapt the marker to the convertView
|
||||
*/
|
||||
public void select(@NonNull MarkerView marker, View convertView, MapboxMap.MarkerViewAdapter adapter) {
|
||||
if (convertView != null) {
|
||||
@@ -210,6 +211,7 @@ public class MarkerViewManager {
|
||||
mapboxMap.selectMarker(marker);
|
||||
}
|
||||
marker.setSelected(true);
|
||||
convertView.bringToFront();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,6 +246,8 @@ public class MarkerViewManager {
|
||||
for (final MapboxMap.MarkerViewAdapter<?> adapter : markerViewAdapters) {
|
||||
if (adapter.getMarkerClass().equals(marker.getClass())) {
|
||||
if (adapter.prepareViewForReuse(marker, viewHolder)) {
|
||||
// reset offset for reuse
|
||||
marker.setOffset(-1, -1);
|
||||
adapter.releaseView(viewHolder);
|
||||
}
|
||||
}
|
||||
@@ -355,7 +359,7 @@ public class MarkerViewManager {
|
||||
adaptedView.setAlpha(marker.getAlpha());
|
||||
|
||||
// visible
|
||||
adaptedView.setVisibility(marker.isVisible() ? View.VISIBLE : View.GONE);
|
||||
adaptedView.setVisibility(View.GONE);
|
||||
|
||||
if (mapboxMap.getSelectedMarkers().contains(marker)) {
|
||||
// if a marker to be shown was selected
|
||||
@@ -374,11 +378,7 @@ public class MarkerViewManager {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -386,7 +386,8 @@ public class MarkerViewManager {
|
||||
|
||||
markerViewMap.put(marker, adaptedView);
|
||||
if (convertView == null) {
|
||||
mapView.addView(adaptedView);
|
||||
adaptedView.setVisibility(View.GONE);
|
||||
mapView.getMarkerViewContainer().addView(adaptedView);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -395,6 +396,42 @@ public class MarkerViewManager {
|
||||
}
|
||||
}
|
||||
|
||||
//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) {
|
||||
int x = (int) (marker.getAnchorU() * view.getMeasuredWidth());
|
||||
int y = (int) (marker.getAnchorV() * view.getMeasuredHeight());
|
||||
marker.setOffset(x, 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
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,7 @@ public class MarkerViewOptions extends BaseMarkerViewOptions<MarkerView, MarkerV
|
||||
infoWindowAnchor(in.readFloat(), in.readFloat());
|
||||
rotation(in.readFloat());
|
||||
visible(in.readByte() != 0);
|
||||
alpha(in.readFloat());
|
||||
if (in.readByte() != 0) {
|
||||
// this means we have an icon
|
||||
String iconId = in.readString();
|
||||
@@ -61,6 +62,7 @@ public class MarkerViewOptions extends BaseMarkerViewOptions<MarkerView, MarkerV
|
||||
out.writeFloat(getInfoWindowAnchorV());
|
||||
out.writeFloat(getRotation());
|
||||
out.writeByte((byte) (isVisible() ? 1 : 0));
|
||||
out.writeFloat(alpha);
|
||||
Icon icon = getIcon();
|
||||
out.writeByte((byte) (icon != null ? 1 : 0));
|
||||
if (icon != null) {
|
||||
@@ -80,6 +82,7 @@ public class MarkerViewOptions extends BaseMarkerViewOptions<MarkerView, MarkerV
|
||||
marker.setInfoWindowAnchor(infoWindowAnchorU, infoWindowAnchorV);
|
||||
marker.setRotation(rotation);
|
||||
marker.setVisible(visible);
|
||||
marker.setAlpha(alpha);
|
||||
return marker;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ import android.view.Surface;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -124,6 +125,7 @@ public class MapView extends FrameLayout {
|
||||
private NativeMapView mNativeMapView;
|
||||
private boolean mHasSurface = false;
|
||||
|
||||
private ViewGroup mMarkerViewContainer;
|
||||
private CompassView mCompassView;
|
||||
private ImageView mLogoView;
|
||||
private ImageView mAttributionsView;
|
||||
@@ -151,6 +153,8 @@ public class MapView extends FrameLayout {
|
||||
private int mContentPaddingRight;
|
||||
private int mContentPaddingBottom;
|
||||
|
||||
private PointF mFocalPoint;
|
||||
|
||||
private StyleInitializer mStyleInitializer;
|
||||
|
||||
private List<OnMapReadyCallback> mOnMapReadyCallbackList;
|
||||
@@ -225,6 +229,8 @@ public class MapView extends FrameLayout {
|
||||
// Connectivity
|
||||
onConnectivityChanged(isConnected());
|
||||
|
||||
mMarkerViewContainer = (ViewGroup) view.findViewById(R.id.markerViewContainer);
|
||||
|
||||
mMyLocationView = (MyLocationView) view.findViewById(R.id.userLocationView);
|
||||
mMyLocationView.setMapboxMap(mMapboxMap);
|
||||
|
||||
@@ -563,6 +569,18 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
void setFocalPoint(PointF focalPoint) {
|
||||
if (focalPoint == null) {
|
||||
// resetting focal point,
|
||||
UiSettings uiSettings = mMapboxMap.getUiSettings();
|
||||
// need to validate if we need to reset focal point with user provided one
|
||||
if (uiSettings.getFocalPoint() != null) {
|
||||
focalPoint = uiSettings.getFocalPoint();
|
||||
}
|
||||
}
|
||||
mFocalPoint = focalPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* You must call this method from the parent's {@link Activity#onLowMemory()} or {@link Fragment#onLowMemory()}.
|
||||
*/
|
||||
@@ -1119,13 +1137,13 @@ public class MapView extends FrameLayout {
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
idsList.add(ids[i]);
|
||||
}
|
||||
|
||||
|
||||
List<MarkerView> annotations = new ArrayList<>(ids.length);
|
||||
List<Annotation> annotationList = mMapboxMap.getAnnotations();
|
||||
int count = annotationList.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
Annotation annotation = annotationList.get(i);
|
||||
if (annotation instanceof MarkerView && idsList.contains(annotation.getId())) {
|
||||
if (annotation instanceof MarkerView) {
|
||||
annotations.add((MarkerView) annotation);
|
||||
}
|
||||
}
|
||||
@@ -1133,6 +1151,13 @@ public class MapView extends FrameLayout {
|
||||
return new ArrayList<>(annotations);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ViewGroup containing the marker views
|
||||
*/
|
||||
public ViewGroup getMarkerViewContainer() {
|
||||
return mMarkerViewContainer;
|
||||
}
|
||||
|
||||
|
||||
int getTopOffsetPixelsForIcon(Icon icon) {
|
||||
if (mDestroyed) {
|
||||
@@ -1371,7 +1396,6 @@ public class MapView extends FrameLayout {
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCompassView.update(getDirection());
|
||||
mMyLocationView.update();
|
||||
mMapboxMap.getMarkerViewManager().update();
|
||||
@@ -1538,8 +1562,12 @@ public class MapView extends FrameLayout {
|
||||
|| mShoveGestureDetector.isInProgress();
|
||||
|
||||
if (mTwoTap && isTap && !inProgress) {
|
||||
PointF focalPoint = TwoFingerGestureDetector.determineFocalPoint(event);
|
||||
zoom(false, focalPoint.x, focalPoint.y);
|
||||
if (mFocalPoint != null) {
|
||||
zoom(false, mFocalPoint.x / mScreenDensity, mFocalPoint.y / mScreenDensity);
|
||||
} else {
|
||||
PointF focalPoint = TwoFingerGestureDetector.determineFocalPoint(event);
|
||||
zoom(false, focalPoint.x, focalPoint.y);
|
||||
}
|
||||
mTwoTap = false;
|
||||
return true;
|
||||
}
|
||||
@@ -1598,12 +1626,12 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Single finger double tap
|
||||
if (mMapboxMap.getTrackingSettings().isLocationTrackingDisabled()) {
|
||||
if (mFocalPoint != null) {
|
||||
// User provided focal point
|
||||
zoom(true, mFocalPoint.x, mFocalPoint.y);
|
||||
} else {
|
||||
// Zoom in on gesture
|
||||
zoom(true, e.getX(), e.getY());
|
||||
} else {
|
||||
// Zoom in on user location view
|
||||
zoom(true, mMyLocationView.getCenterX(), mMyLocationView.getCenterY());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1678,8 +1706,10 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// deselect any selected marker
|
||||
mMapboxMap.deselectMarkers();
|
||||
if (mMapboxMap.getUiSettings().isDeselectMarkersOnTap()) {
|
||||
// deselect any selected marker
|
||||
mMapboxMap.deselectMarkers();
|
||||
}
|
||||
|
||||
// notify app of map click
|
||||
MapboxMap.OnMapClickListener listener = mMapboxMap.getOnMapClickListener();
|
||||
@@ -1835,23 +1865,18 @@ public class MapView extends FrameLayout {
|
||||
// Gesture is a quickzoom if there aren't two fingers
|
||||
mQuickZoom = !mTwoTap;
|
||||
|
||||
TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
|
||||
|
||||
// Scale the map
|
||||
if (uiSettings.isScrollGesturesEnabled() && !mQuickZoom && trackingSettings.isLocationTrackingDisabled()) {
|
||||
if (mFocalPoint != null) {
|
||||
// arround user provided focal point
|
||||
mNativeMapView.scaleBy(detector.getScaleFactor(), mFocalPoint.x / mScreenDensity, mFocalPoint.y / mScreenDensity);
|
||||
} else if (mQuickZoom) {
|
||||
// around center map
|
||||
mNativeMapView.scaleBy(detector.getScaleFactor(), (getWidth() / 2) / mScreenDensity, (getHeight() / 2) / mScreenDensity);
|
||||
} else {
|
||||
// around gesture
|
||||
mNativeMapView.scaleBy(detector.getScaleFactor(), detector.getFocusX() / mScreenDensity, detector.getFocusY() / mScreenDensity);
|
||||
} else {
|
||||
if (trackingSettings.isLocationTrackingDisabled()) {
|
||||
// around center map
|
||||
mNativeMapView.scaleBy(detector.getScaleFactor(), (getWidth() / 2) / mScreenDensity, (getHeight() / 2) / mScreenDensity);
|
||||
} else {
|
||||
// around user location view
|
||||
float x = mMyLocationView.getX() + mMyLocationView.getWidth() / 2;
|
||||
float y = mMyLocationView.getY() + mMyLocationView.getHeight() / 2;
|
||||
mNativeMapView.scaleBy(detector.getScaleFactor(), x / mScreenDensity, y / mScreenDensity);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1925,16 +1950,14 @@ public class MapView extends FrameLayout {
|
||||
bearing += detector.getRotationDegreesDelta();
|
||||
|
||||
// Rotate the map
|
||||
if (mMapboxMap.getTrackingSettings().isLocationTrackingDisabled()) {
|
||||
if (mFocalPoint != null) {
|
||||
// User provided focal point
|
||||
mNativeMapView.setBearing(bearing, mFocalPoint.x / mScreenDensity, mFocalPoint.y / mScreenDensity);
|
||||
} else {
|
||||
// around gesture
|
||||
mNativeMapView.setBearing(bearing,
|
||||
detector.getFocusX() / mScreenDensity,
|
||||
detector.getFocusY() / mScreenDensity);
|
||||
} else {
|
||||
// around center userlocation
|
||||
float x = mMyLocationView.getX() + mMyLocationView.getWidth() / 2;
|
||||
float y = mMyLocationView.getY() + mMyLocationView.getHeight() / 2;
|
||||
mNativeMapView.setBearing(bearing, x / mScreenDensity, y / mScreenDensity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -2429,6 +2452,13 @@ public class MapView extends FrameLayout {
|
||||
mMapboxMap.setMyLocationEnabled(true);
|
||||
}
|
||||
mMyLocationView.setMyLocationTrackingMode(myLocationTrackingMode);
|
||||
|
||||
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
|
||||
setFocalPoint(new PointF(mMyLocationView.getCenterX(), mMyLocationView.getCenterY()));
|
||||
} else {
|
||||
setFocalPoint(null);
|
||||
}
|
||||
|
||||
MapboxMap.OnMyLocationTrackingModeChangeListener listener = mMapboxMap.getOnMyLocationTrackingModeChangeListener();
|
||||
if (listener != null) {
|
||||
listener.onMyLocationTrackingModeChange(myLocationTrackingMode);
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.mapbox.mapboxsdk.annotations.Annotation;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.annotations.InfoWindow;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
@@ -38,7 +39,6 @@ import com.mapbox.mapboxsdk.constants.MyLocationTracking;
|
||||
import com.mapbox.mapboxsdk.constants.Style;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.layers.CustomLayer;
|
||||
import com.mapbox.mapboxsdk.location.LocationListener;
|
||||
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
@@ -52,7 +52,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* you must obtain one from the getMapAsync() method on a MapFragment or MapView that you have
|
||||
* added to your application.
|
||||
* <p>
|
||||
* Note: Similar to a View object, a GoogleMap should only be read and modified from the main thread.
|
||||
* Note: Similar to a View object, a MapboxMap should only be read and modified from the main thread.
|
||||
* </p>
|
||||
*/
|
||||
public class MapboxMap {
|
||||
@@ -1142,6 +1142,11 @@ public class MapboxMap {
|
||||
}
|
||||
|
||||
if (!handledDefaultClick) {
|
||||
|
||||
if (marker instanceof MarkerView) {
|
||||
mMarkerViewManager.ensureInfoWindowOffset((MarkerView) marker);
|
||||
}
|
||||
|
||||
if (isInfoWindowValidForMarker(marker) || getInfoWindowAdapter() != null) {
|
||||
mInfoWindows.add(marker.showInfoWindow(this, mMapView));
|
||||
}
|
||||
@@ -1208,7 +1213,12 @@ public class MapboxMap {
|
||||
|
||||
private MarkerView prepareViewMarker(BaseMarkerViewOptions markerViewOptions) {
|
||||
MarkerView marker = markerViewOptions.getMarker();
|
||||
marker.setIcon(markerViewOptions.getIcon());
|
||||
|
||||
Icon icon = markerViewOptions.getIcon();
|
||||
if (icon == null) {
|
||||
icon = IconFactory.getInstance(mMapView.getContext()).defaultMarkerView();
|
||||
}
|
||||
marker.setIcon(icon);
|
||||
return marker;
|
||||
}
|
||||
|
||||
@@ -1533,10 +1543,8 @@ public class MapboxMap {
|
||||
*
|
||||
* @param listener The callback that's invoked when the user clicks on a marker.
|
||||
* To unset the callback, use null.
|
||||
* @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.location.LocationServices#addLocationListener(LocationListener)})}
|
||||
*/
|
||||
@UiThread
|
||||
@Deprecated
|
||||
public void setOnMyLocationChangeListener(@Nullable MapboxMap.OnMyLocationChangeListener listener) {
|
||||
mMapView.setOnMyLocationChangeListener(listener);
|
||||
}
|
||||
@@ -1945,9 +1953,7 @@ public class MapboxMap {
|
||||
* Interface definition for a callback to be invoked when the the My Location view changes location.
|
||||
*
|
||||
* @see MapboxMap#setOnMyLocationChangeListener(OnMyLocationChangeListener)
|
||||
* @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.location.LocationListener}
|
||||
*/
|
||||
@Deprecated
|
||||
public interface OnMyLocationChangeListener {
|
||||
/**
|
||||
* Called when the location of the My Location view has changed
|
||||
|
||||
@@ -101,7 +101,7 @@ public class TrackingSettings {
|
||||
*
|
||||
* @return True to indicate the tracking modes will be dismissed.
|
||||
* @deprecated use @link #isAllDismissTrackingOnGestureinstead
|
||||
*/
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isDismissTrackingOnGesture() {
|
||||
return dismissLocationTrackingOnGesture && dismissBearingTrackingOnGesture;
|
||||
@@ -215,7 +215,7 @@ public class TrackingSettings {
|
||||
private void validateGesturesForBearingTrackingMode() {
|
||||
int myBearingTrackingMode = getMyBearingTrackingMode();
|
||||
if (!dismissBearingTrackingOnGesture) {
|
||||
if (myBearingTrackingMode == MyBearingTracking.NONE) {
|
||||
if (myBearingTrackingMode == MyBearingTracking.NONE || myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
|
||||
uiSettings.setRotateGesturesEnabled(true);
|
||||
} else {
|
||||
uiSettings.setRotateGesturesEnabled(false);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
@@ -33,6 +35,10 @@ public class UiSettings {
|
||||
|
||||
private boolean zoomControlsEnabled;
|
||||
|
||||
private boolean deselectMarkersOnTap = true;
|
||||
|
||||
private PointF focalPoint;
|
||||
|
||||
UiSettings(@NonNull MapView mapView) {
|
||||
this.mapView = mapView;
|
||||
this.compassSettings = new ViewSettings();
|
||||
@@ -483,6 +489,26 @@ public class UiSettings {
|
||||
return zoomControlsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the markers are automatically deselected (and therefore, their infowindows
|
||||
* closed) when a map tap is detected.
|
||||
|
||||
* @return If true, markers are deselected on a map tap.
|
||||
*/
|
||||
public boolean isDeselectMarkersOnTap() {
|
||||
return deselectMarkersOnTap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the markers are automatically deselected (and therefore, their infowindows
|
||||
* closed) when a map tap is detected.
|
||||
*
|
||||
* @param deselectMarkersOnTap
|
||||
*/
|
||||
public void setDeselectMarkersOnTap(boolean deselectMarkersOnTap) {
|
||||
this.deselectMarkersOnTap = deselectMarkersOnTap;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Changes whether the user may scroll around the map.
|
||||
@@ -541,6 +567,25 @@ public class UiSettings {
|
||||
setZoomGesturesEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the focal point used as center for a gesture
|
||||
*
|
||||
* @param focalPoint the focal point to be used.
|
||||
*/
|
||||
public void setFocalPoint(@Nullable PointF focalPoint) {
|
||||
this.focalPoint = focalPoint;
|
||||
mapView.setFocalPoint(focalPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gesture focal point
|
||||
*
|
||||
* @return The focal point
|
||||
*/
|
||||
public PointF getFocalPoint() {
|
||||
return focalPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the measured height of the MapView
|
||||
*
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.mapbox.mapboxsdk.maps.widgets;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Camera;
|
||||
@@ -28,7 +27,6 @@ import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.mapbox.mapboxsdk.R;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
|
||||
@@ -67,6 +65,14 @@ public class MyLocationView extends View {
|
||||
private ValueAnimator accuracyAnimator;
|
||||
private ValueAnimator directionAnimator;
|
||||
|
||||
private ValueAnimator.AnimatorUpdateListener invalidateSelfOnUpdateListener =
|
||||
new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
invalidate();
|
||||
}
|
||||
};
|
||||
|
||||
private Drawable foregroundDrawable;
|
||||
private Drawable foregroundBearingDrawable;
|
||||
private Drawable backgroundDrawable;
|
||||
@@ -260,8 +266,8 @@ public class MyLocationView extends View {
|
||||
camera.getMatrix(matrix);
|
||||
|
||||
//
|
||||
if (myBearingTrackingMode != MyBearingTracking.NONE) {
|
||||
matrix.postRotate((Float) directionAnimator.getAnimatedValue());
|
||||
if (myBearingTrackingMode != MyBearingTracking.NONE && directionAnimator != null) {
|
||||
matrix.preRotate((Float) directionAnimator.getAnimatedValue());
|
||||
}
|
||||
|
||||
// put matrix at location of MyLocationView
|
||||
@@ -295,10 +301,6 @@ public class MyLocationView extends View {
|
||||
this.tilt = (float) tilt;
|
||||
}
|
||||
|
||||
void updateOnNextFrame() {
|
||||
mapboxMap.invalidate();
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
compassListener.onPause();
|
||||
toggleGps(false);
|
||||
@@ -444,6 +446,7 @@ public class MyLocationView extends View {
|
||||
|
||||
directionAnimator = ValueAnimator.ofFloat(oldDir, newDir);
|
||||
directionAnimator.setDuration(375);
|
||||
directionAnimator.addUpdateListener(invalidateSelfOnUpdateListener);
|
||||
directionAnimator.start();
|
||||
}
|
||||
|
||||
@@ -526,24 +529,19 @@ public class MyLocationView extends View {
|
||||
return;
|
||||
}
|
||||
|
||||
long currentTime = SystemClock.elapsedRealtime();
|
||||
if (currentTime < mCompassUpdateNextTimestamp) {
|
||||
return;
|
||||
}
|
||||
|
||||
int type = event.sensor.getType();
|
||||
float[] data;
|
||||
if (type == Sensor.TYPE_ACCELEROMETER) {
|
||||
data = mGData;
|
||||
System.arraycopy(event.values, 0, mGData, 0, 3);
|
||||
} else if (type == Sensor.TYPE_MAGNETIC_FIELD) {
|
||||
data = mMData;
|
||||
System.arraycopy(event.values, 0, mMData, 0, 3);
|
||||
} else {
|
||||
// we should not be here.
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
data[i] = event.values[i];
|
||||
long currentTime = SystemClock.elapsedRealtime();
|
||||
if (currentTime < mCompassUpdateNextTimestamp) {
|
||||
return;
|
||||
}
|
||||
|
||||
SensorManager.getRotationMatrix(mR, mI, mGData, mMData);
|
||||
@@ -587,7 +585,7 @@ public class MyLocationView extends View {
|
||||
double latitude = fromLat + (toLat - fromLat) * frac;
|
||||
double longitude = fromLng + (toLng - fromLng) * frac;
|
||||
behavior.updateLatLng(latitude, longitude);
|
||||
updateOnNextFrame();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -313,6 +313,16 @@ public class MapboxEventManager {
|
||||
* @param location Location event
|
||||
*/
|
||||
public void addLocationEvent(Location location) {
|
||||
|
||||
// NaN and Infinite checks to prevent JSON errors at send to server time
|
||||
if (Double.isNaN(location.getLatitude()) || Double.isNaN(location.getLongitude()) || Double.isNaN(location.getAltitude())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Double.isInfinite(location.getLatitude()) || Double.isInfinite(location.getLongitude()) || Double.isInfinite(location.getAltitude())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add Location even to queue
|
||||
Hashtable<String, Object> event = new Hashtable<>();
|
||||
event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_LOCATION);
|
||||
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
@@ -6,6 +6,11 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/markerViewContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<com.mapbox.mapboxsdk.maps.widgets.CompassView
|
||||
android:id="@+id/compassView"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
fabric-identifier=com.mapbox.mapboxsdk.mapbox-android-sdk
|
||||
fabric-version=4.1.0-beta.2
|
||||
fabric-version=4.1.0
|
||||
fabric-build-type=binary
|
||||
|
||||
@@ -90,13 +90,8 @@ dependencies {
|
||||
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta1'
|
||||
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
|
||||
|
||||
// Directions SDK
|
||||
compile('com.mapbox.mapboxsdk:mapbox-android-directions:1.0.0@aar') {
|
||||
transitive = true
|
||||
}
|
||||
|
||||
// Geocoder SDK
|
||||
compile('com.mapbox.mapboxsdk:mapbox-android-geocoder:1.0.0@aar') {
|
||||
// Mapbox Android Services
|
||||
compile('com.mapbox.mapboxsdk:mapbox-android-services:1.1.0@aar') {
|
||||
transitive = true
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,14 @@
|
||||
android:name="@string/category"
|
||||
android:value="@string/category_infowindow" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.infowindow.DynamicInfoWindowAdapterActivity"
|
||||
android:description="@string/description_dynamic_info_window_adapter"
|
||||
android:label="@string/activity_dynamic_infowindow_adapter">
|
||||
<meta-data
|
||||
android:name="@string/category"
|
||||
android:value="@string/category_infowindow"/>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.annotation.BulkMarkerActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
@@ -261,6 +269,22 @@
|
||||
android:name="@string/category"
|
||||
android:value="@string/category_annotation" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.annotation.MarkerViewScaleActivity"
|
||||
android:description="@string/description_view_marker_scale"
|
||||
android:label="@string/activity_view_marker_scale">
|
||||
<meta-data
|
||||
android:name="@string/category"
|
||||
android:value="@string/category_annotation" />
|
||||
</activity>
|
||||
|
||||
<activity android:name=".activity.navigation.LocationPickerActivity"
|
||||
android:description="@string/description_location_picker"
|
||||
android:label="@string/activity_location_picker">
|
||||
<meta-data
|
||||
android:name="@string/category"
|
||||
android:value="@string/category_navigation" />
|
||||
</activity>
|
||||
|
||||
<!-- Configuration Settings -->
|
||||
<meta-data
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
@@ -9,7 +10,11 @@ import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
@@ -61,10 +66,16 @@ public class FeatureOverviewActivity extends AppCompatActivity {
|
||||
@Override
|
||||
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
|
||||
if (!sectionAdapter.isSectionHeaderPosition(position)) {
|
||||
Intent intent = new Intent();
|
||||
int realPosition = sectionAdapter.getConvertedPosition(position);
|
||||
intent.setComponent(new ComponentName(getPackageName(), features.get(realPosition).getName()));
|
||||
startActivity(intent);
|
||||
Feature feature = features.get(realPosition);
|
||||
if (feature.getCategory().equals(getString(R.string.category_userlocation))) {
|
||||
if ((ContextCompat.checkSelfPermission(FeatureOverviewActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) ||
|
||||
(ContextCompat.checkSelfPermission(FeatureOverviewActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
|
||||
ActivityCompat.requestPermissions(FeatureOverviewActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, realPosition);
|
||||
return;
|
||||
}
|
||||
}
|
||||
startFeature(feature);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -104,6 +115,22 @@ public class FeatureOverviewActivity extends AppCompatActivity {
|
||||
recyclerView.setAdapter(sectionAdapter);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
startFeature(features.get(requestCode));
|
||||
}else{
|
||||
Snackbar.make(findViewById(android.R.id.content),"Can't open without the location permission.",Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void startFeature(Feature feature) {
|
||||
Intent intent = new Intent();
|
||||
intent.setComponent(new ComponentName(getPackageName(), feature.getName()));
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
@@ -1,27 +1,44 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.annotation;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.TypeEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerView;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class AnimatedMarkerActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mMapView;
|
||||
private MapboxMap mMapboxMap;
|
||||
private Random random = new Random();
|
||||
|
||||
private LatLng dupontCircle = new LatLng(38.90962, -77.04341);
|
||||
|
||||
private Marker passengerMarker = null;
|
||||
private MarkerView carMarker = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -40,34 +57,121 @@ public class AnimatedMarkerActivity extends AppCompatActivity {
|
||||
mMapView = (MapView) findViewById(R.id.mapView);
|
||||
mMapView.onCreate(savedInstanceState);
|
||||
mMapView.getMapAsync(new OnMapReadyCallback() {
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
|
||||
LatLng brussels = new LatLng(50.900446, 4.485251);
|
||||
LatLng washington = new LatLng(38.897108, -77.036716);
|
||||
mMapboxMap = mapboxMap;
|
||||
setupMap();
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
addRandomCar();
|
||||
}
|
||||
|
||||
final Marker marker = mapboxMap.addMarker(new MarkerOptions().position(brussels));
|
||||
ValueAnimator markerAnimator = ValueAnimator.ofObject(new LatLngEvaluator(), (Object[]) new LatLng[]{brussels, washington});
|
||||
markerAnimator.setDuration(5000);
|
||||
markerAnimator.setRepeatCount(ValueAnimator.INFINITE);
|
||||
markerAnimator.setRepeatMode(ValueAnimator.REVERSE);
|
||||
markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
|
||||
markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
if (marker != null) {
|
||||
marker.setPosition((LatLng) animation.getAnimatedValue());
|
||||
}
|
||||
}
|
||||
});
|
||||
markerAnimator.start();
|
||||
addPassenger();
|
||||
addMainCar();
|
||||
animateMoveToPassenger(carMarker);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_zoom, menu);
|
||||
return true;
|
||||
private void setupMap() {
|
||||
CameraPosition cameraPosition = new CameraPosition.Builder()
|
||||
.target(dupontCircle)
|
||||
.zoom(15)
|
||||
.build();
|
||||
mMapboxMap.setCameraPosition(cameraPosition);
|
||||
}
|
||||
|
||||
private void addPassenger() {
|
||||
LatLng randomLatLng = getLatLngInBounds();
|
||||
|
||||
if (passengerMarker == null) {
|
||||
Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this)
|
||||
.fromResource(R.drawable.ic_directions_run_black_24dp);
|
||||
passengerMarker = mMapboxMap.addMarker(new MarkerViewOptions()
|
||||
.position(randomLatLng)
|
||||
.icon(icon));
|
||||
} else {
|
||||
passengerMarker.setPosition(randomLatLng);
|
||||
}
|
||||
}
|
||||
|
||||
private void addMainCar() {
|
||||
LatLng randomLatLng = getLatLngInBounds();
|
||||
|
||||
if (carMarker == null) {
|
||||
carMarker = createCarMarker(randomLatLng, R.drawable.ic_taxi_top);
|
||||
} else {
|
||||
carMarker.setPosition(randomLatLng);
|
||||
}
|
||||
|
||||
// Make sure the car marker is selected so that it's always brought to the front (#5285)
|
||||
mMapboxMap.selectMarker(carMarker);
|
||||
}
|
||||
|
||||
private void animateMoveToPassenger(final MarkerView car) {
|
||||
ValueAnimator animator = animateMoveMarker(car, passengerMarker.getPosition());
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
addPassenger();
|
||||
animateMoveToPassenger(car);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void addRandomCar() {
|
||||
MarkerView car = createCarMarker(getLatLngInBounds(), R.drawable.ic_car_top);
|
||||
randomlyMoveMarker(car);
|
||||
}
|
||||
|
||||
private void randomlyMoveMarker(final MarkerView marker) {
|
||||
ValueAnimator animator = animateMoveMarker(marker, getLatLngInBounds());
|
||||
|
||||
//Add listener to restart animation on end
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
randomlyMoveMarker(marker);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ValueAnimator animateMoveMarker(final MarkerView marker, LatLng to) {
|
||||
marker.setRotation((float) getBearing(marker.getPosition(), to));
|
||||
|
||||
final ValueAnimator markerAnimator = ObjectAnimator.ofObject(marker, "position", new LatLngEvaluator(), marker.getPosition(), to);
|
||||
markerAnimator.setDuration((long) (10 * marker.getPosition().distanceTo(to)));
|
||||
markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
|
||||
|
||||
// Start
|
||||
markerAnimator.start();
|
||||
|
||||
return markerAnimator;
|
||||
}
|
||||
|
||||
private MarkerView createCarMarker(LatLng start, @DrawableRes int carResource) {
|
||||
Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this)
|
||||
.fromResource(carResource);
|
||||
|
||||
//View Markers
|
||||
return mMapboxMap.addMarker(new MarkerViewOptions()
|
||||
.position(start)
|
||||
.icon(icon));
|
||||
|
||||
//GL Markers
|
||||
// return mMapboxMap.addMarker(new MarkerOptions()
|
||||
// .position(start)
|
||||
// .icon(icon));
|
||||
|
||||
}
|
||||
|
||||
private LatLng getLatLngInBounds() {
|
||||
LatLngBounds bounds = mMapboxMap.getProjection().getVisibleRegion().latLngBounds;
|
||||
Random generator = new Random();
|
||||
double randomLat = bounds.getLatSouth() + generator.nextDouble() * (bounds.getLatNorth() - bounds.getLatSouth());
|
||||
double randomLon = bounds.getLonWest() + generator.nextDouble() * (bounds.getLonEast() - bounds.getLonWest());
|
||||
return new LatLng(randomLat, randomLon);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,15 +215,33 @@ public class AnimatedMarkerActivity extends AppCompatActivity {
|
||||
mMapView.onLowMemory();
|
||||
}
|
||||
|
||||
private class LatLngEvaluator implements TypeEvaluator<LatLng> {
|
||||
/**
|
||||
* Evaluator for LatLng pairs
|
||||
*/
|
||||
private static class LatLngEvaluator implements TypeEvaluator<LatLng> {
|
||||
|
||||
private LatLng mLatLng = new LatLng();
|
||||
|
||||
@Override
|
||||
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
|
||||
mLatLng.setLatitude(startValue.getLatitude() + (endValue.getLatitude() - startValue.getLatitude()) * fraction);
|
||||
mLatLng.setLongitude(startValue.getLongitude() + (endValue.getLongitude() - startValue.getLongitude()) * fraction);
|
||||
mLatLng.setLatitude(startValue.getLatitude() + ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
|
||||
mLatLng.setLongitude(startValue.getLongitude() + ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
|
||||
return mLatLng;
|
||||
}
|
||||
}
|
||||
|
||||
private double getBearing(LatLng from, LatLng to) {
|
||||
double degrees2radians = Math.PI / 180;
|
||||
double radians2degrees = 180 / Math.PI;
|
||||
|
||||
double lon1 = degrees2radians * from.getLongitude();
|
||||
double lon2 = degrees2radians * to.getLongitude();
|
||||
double lat1 = degrees2radians * from.getLatitude();
|
||||
double lat2 = degrees2radians * to.getLatitude();
|
||||
double a = Math.sin(lon2 - lon1) * Math.cos(lat2);
|
||||
double b = Math.cos(lat1) * Math.sin(lat2) -
|
||||
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
|
||||
|
||||
return radians2degrees * Math.atan2(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.animation.AnimatorInflater;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
@@ -55,7 +56,8 @@ public class MarkerViewActivity extends AppCompatActivity {
|
||||
new LatLng(38.909698, -77.029642),
|
||||
new LatLng(38.907227, -77.036530),
|
||||
new LatLng(38.905607, -77.031916),
|
||||
new LatLng(38.889441, -77.050134)
|
||||
new LatLng(38.889441, -77.050134),
|
||||
new LatLng(38.888000, -77.050000) //Slight overlap to show re-ordering on selection
|
||||
};
|
||||
|
||||
@Override
|
||||
@@ -90,6 +92,7 @@ public class MarkerViewActivity extends AppCompatActivity {
|
||||
mMapboxMap.addMarker(new MarkerViewOptions()
|
||||
.position(LAT_LNGS[i])
|
||||
.title(String.valueOf(i))
|
||||
.alpha(0.5f)
|
||||
.icon(usFlag)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.annotation;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerView;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class MarkerViewScaleActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mMapView;
|
||||
private View mMarkerView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_marker_view_scale);
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
final ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(true);
|
||||
}
|
||||
|
||||
final SeekBar xBar = (SeekBar) findViewById(R.id.seekbar_factor);
|
||||
TextView xText = (TextView) findViewById(R.id.textview_factor);
|
||||
xBar.setOnSeekBarChangeListener(new FactorChangeListener(xText));
|
||||
|
||||
mMapView = (MapView) findViewById(R.id.mapView);
|
||||
mMapView.onCreate(savedInstanceState);
|
||||
mMapView.getMapAsync(new OnMapReadyCallback() {
|
||||
@Override
|
||||
public void onMapReady(MapboxMap mapboxMap) {
|
||||
Icon icon = IconFactory.getInstance(MarkerViewScaleActivity.this)
|
||||
.fromResource(R.drawable.ic_circle);
|
||||
|
||||
MarkerView mMarker = mapboxMap.addMarker(new MarkerViewOptions()
|
||||
.position(new LatLng(38.907192, -77.036871))
|
||||
.icon(icon)
|
||||
.flat(true));
|
||||
|
||||
mMarkerView = mapboxMap.getMarkerViewManager().getView(mMarker);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mMapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mMapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mMapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mMapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mMapView.onLowMemory();
|
||||
}
|
||||
|
||||
private class FactorChangeListener implements SeekBar.OnSeekBarChangeListener {
|
||||
|
||||
private TextView xText;
|
||||
|
||||
public FactorChangeListener(TextView xText) {
|
||||
this.xText = xText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
float newScale = getScale(progress);
|
||||
xText.setText(String.format(Locale.US, "Scale: %.1f", newScale));
|
||||
if (MarkerViewScaleActivity.this.mMarkerView != null) {
|
||||
mMarkerView.setScaleX(newScale);
|
||||
mMarkerView.setScaleY(newScale);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
// Not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
// Not used
|
||||
}
|
||||
|
||||
private float getScale(int progress) {
|
||||
float scale = 1.0f * progress / 25;
|
||||
return scale < 1.0 ? 1.0f : scale;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,12 +8,6 @@ import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.mapbox.directions.DirectionsCriteria;
|
||||
import com.mapbox.directions.MapboxDirections;
|
||||
import com.mapbox.directions.service.models.DirectionsResponse;
|
||||
import com.mapbox.directions.service.models.DirectionsRoute;
|
||||
import com.mapbox.directions.service.models.Waypoint;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
@@ -23,12 +17,18 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit.Callback;
|
||||
import retrofit.Response;
|
||||
import retrofit.Retrofit;
|
||||
import com.mapbox.services.Constants;
|
||||
import com.mapbox.services.commons.ServicesException;
|
||||
import com.mapbox.services.commons.geojson.LineString;
|
||||
import com.mapbox.services.commons.models.Position;
|
||||
import com.mapbox.services.directions.v4.DirectionsCriteria;
|
||||
import com.mapbox.services.directions.v4.MapboxDirections;
|
||||
import com.mapbox.services.directions.v4.models.DirectionsResponse;
|
||||
import com.mapbox.services.directions.v4.models.DirectionsRoute;
|
||||
import com.mapbox.services.directions.v4.models.Waypoint;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class DirectionsActivity extends AppCompatActivity {
|
||||
|
||||
@@ -94,49 +94,55 @@ public class DirectionsActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void getRoute(Waypoint origin, Waypoint destination) {
|
||||
MapboxDirections md = new MapboxDirections.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setOrigin(origin)
|
||||
.setDestination(destination)
|
||||
.setProfile(DirectionsCriteria.PROFILE_WALKING)
|
||||
.build();
|
||||
try {
|
||||
MapboxDirections md = new MapboxDirections.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setOrigin(origin)
|
||||
.setDestination(destination)
|
||||
.setProfile(DirectionsCriteria.PROFILE_WALKING)
|
||||
.build();
|
||||
|
||||
md.enqueue(new Callback<DirectionsResponse>() {
|
||||
@Override
|
||||
public void onResponse(Response<DirectionsResponse> response, Retrofit retrofit) {
|
||||
// You can get generic HTTP info about the response
|
||||
Log.d(LOG_TAG, "Response code: " + response.code());
|
||||
md.enqueueCall(new Callback<DirectionsResponse>() {
|
||||
|
||||
// Print some info about the route
|
||||
DirectionsRoute currentRoute = response.body().getRoutes().get(0);
|
||||
Log.d(LOG_TAG, "Distance: " + currentRoute.getDistance());
|
||||
@Override
|
||||
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
|
||||
Log.e(LOG_TAG, "Error: " + t.getMessage());
|
||||
}
|
||||
|
||||
// Draw the route on the map
|
||||
drawRoute(currentRoute);
|
||||
}
|
||||
@Override
|
||||
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
|
||||
// You can get generic HTTP info about the response
|
||||
Log.d(LOG_TAG, "Response code: " + response.code());
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
Log.e(LOG_TAG, "Error: " + t.getMessage());
|
||||
}
|
||||
});
|
||||
// Print some info about the route
|
||||
DirectionsRoute currentRoute = response.body().getRoutes().get(0);
|
||||
Log.d(LOG_TAG, "Distance: " + currentRoute.getDistance());
|
||||
|
||||
// Draw the route on the map
|
||||
drawRoute(currentRoute);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (ServicesException e) {
|
||||
Log.e(LOG_TAG, "Error displaying route: " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void drawRoute(DirectionsRoute route) {
|
||||
// Convert List<Waypoint> into LatLng[]
|
||||
List<Waypoint> waypoints = route.getGeometry().getWaypoints();
|
||||
LatLng[] point = new LatLng[waypoints.size()];
|
||||
for (int i = 0; i < waypoints.size(); i++) {
|
||||
point[i] = new LatLng(
|
||||
waypoints.get(i).getLatitude(),
|
||||
waypoints.get(i).getLongitude());
|
||||
|
||||
PolylineOptions builder = new PolylineOptions();
|
||||
builder.color(Color.parseColor("#3887be"));
|
||||
builder.alpha(0.5f);
|
||||
builder.width(5);
|
||||
builder.width(5);
|
||||
LineString lineString = route.asLineString(Constants.OSRM_PRECISION_V4);
|
||||
for (Position coordinates : lineString.getCoordinates()) {
|
||||
builder.add(new LatLng(coordinates.getLatitude(), coordinates.getLongitude()));
|
||||
}
|
||||
|
||||
// Draw Points on MapView
|
||||
mMapboxMap.addPolyline(new PolylineOptions()
|
||||
.add(point)
|
||||
.color(Color.parseColor("#3887be"))
|
||||
.width(5));
|
||||
mMapboxMap.addPolyline(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,11 +14,6 @@ import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapbox.geocoder.GeocoderCriteria;
|
||||
import com.mapbox.geocoder.MapboxGeocoder;
|
||||
import com.mapbox.geocoder.service.models.GeocoderFeature;
|
||||
import com.mapbox.geocoder.service.models.GeocoderResponse;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.constants.Style;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
@@ -27,12 +22,19 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Projection;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.services.commons.ServicesException;
|
||||
import com.mapbox.services.commons.models.Position;
|
||||
import com.mapbox.services.geocoding.v5.GeocodingCriteria;
|
||||
import com.mapbox.services.geocoding.v5.MapboxGeocoding;
|
||||
import com.mapbox.services.geocoding.v5.models.GeocodingFeature;
|
||||
import com.mapbox.services.geocoding.v5.models.GeocodingResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit.Callback;
|
||||
import retrofit.Response;
|
||||
import retrofit.Retrofit;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
public class GeocoderActivity extends AppCompatActivity {
|
||||
|
||||
@@ -123,40 +125,38 @@ public class GeocoderActivity extends AppCompatActivity {
|
||||
*/
|
||||
|
||||
private void geocode(final LatLng point) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
MapboxGeocoder client = new MapboxGeocoder.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setCoordinates(point.getLongitude(), point.getLatitude())
|
||||
.setType(GeocoderCriteria.TYPE_POI)
|
||||
.build();
|
||||
try {
|
||||
MapboxGeocoding client = new MapboxGeocoding.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setCoordinates(Position.fromCoordinates(point.getLongitude(), point.getLatitude()))
|
||||
.setType(GeocodingCriteria.TYPE_POI)
|
||||
.build();
|
||||
|
||||
client.enqueue(new Callback<GeocoderResponse>()
|
||||
client.enqueueCall(new Callback<GeocodingResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {
|
||||
|
||||
{
|
||||
@Override
|
||||
public void onResponse(Response<GeocoderResponse> response, Retrofit retrofit) {
|
||||
List<GeocoderFeature> results = response.body().getFeatures();
|
||||
if (results.size() > 0) {
|
||||
String placeName = results.get(0).getPlaceName();
|
||||
setSuccess(placeName);
|
||||
} else {
|
||||
setMessage("No results.");
|
||||
}
|
||||
}
|
||||
List<GeocodingFeature> results = response.body().getFeatures();
|
||||
if (results.size() > 0) {
|
||||
String placeName = results.get(0).getPlaceName();
|
||||
setSuccess(placeName);
|
||||
} else {
|
||||
setMessage("No results.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
setError(t.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
@Override
|
||||
public void onFailure(Call<GeocodingResponse> call, Throwable t) {
|
||||
setError(t.getMessage());
|
||||
}
|
||||
});
|
||||
} catch (ServicesException e) {
|
||||
Log.e(LOG_TAG, "Error geocoding: " + e.toString());
|
||||
e.printStackTrace();
|
||||
setError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.infowindow;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.annotations.InfoWindow;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerView;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
/**
|
||||
* Shows how to dynamically update InfoWindow when Using an MapboxMap.InfoWindowAdapter
|
||||
*/
|
||||
public class DynamicInfoWindowAdapterActivity extends AppCompatActivity {
|
||||
|
||||
private MapView mapView;
|
||||
|
||||
private LatLng paris = new LatLng(48.864716, 2.349014);
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_infowindow_adapter);
|
||||
|
||||
setupActionBar();
|
||||
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
mapView.getMapAsync(new OnMapReadyCallback() {
|
||||
@Override
|
||||
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
|
||||
//Add info window adapter
|
||||
addCustomInfoWindowAdapter(mapboxMap);
|
||||
|
||||
//Keep info windows open on click
|
||||
mapboxMap.getUiSettings().setDeselectMarkersOnTap(false);
|
||||
|
||||
//Add a marker
|
||||
final MarkerView marker = addMarker(mapboxMap);
|
||||
mapboxMap.selectMarker(marker);
|
||||
|
||||
//On map click, change the info window contents
|
||||
mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
|
||||
@Override
|
||||
public void onMapClick(@NonNull LatLng point) {
|
||||
//Distance from click to marker
|
||||
double distanceKm = marker.getPosition().distanceTo(point) / 1000;
|
||||
|
||||
//Get the info window
|
||||
InfoWindow infoWindow = marker.getInfoWindow();
|
||||
|
||||
//Get the view from the info window
|
||||
if (infoWindow != null && infoWindow.getView() != null) {
|
||||
//Set the new text on the text view in the info window
|
||||
((TextView) infoWindow.getView()).setText(String.format("%.2fkm", distanceKm));
|
||||
|
||||
//Update the info window position (as the text length changes)
|
||||
infoWindow.update();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Focus on Paris
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newLatLng(paris));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private MarkerView addMarker(MapboxMap mapboxMap) {
|
||||
IconFactory iconFactory = IconFactory.getInstance(this);
|
||||
Drawable iconDrawable = ContextCompat.getDrawable(this, R.drawable.ic_location_city_24dp);
|
||||
iconDrawable.setColorFilter(getResources().getColor(R.color.mapbox_blue), PorterDuff.Mode.SRC_IN);
|
||||
|
||||
return mapboxMap.addMarker(
|
||||
new MarkerViewOptions()
|
||||
.position(paris)
|
||||
.icon(iconFactory.fromDrawable(iconDrawable))
|
||||
);
|
||||
}
|
||||
|
||||
private void addCustomInfoWindowAdapter(final MapboxMap mapboxMap) {
|
||||
final int padding = (int) getResources().getDimension(R.dimen.attr_margin);
|
||||
mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View getInfoWindow(@NonNull Marker marker) {
|
||||
TextView textView = new TextView(DynamicInfoWindowAdapterActivity.this);
|
||||
textView.setText(marker.getTitle());
|
||||
textView.setBackgroundColor(Color.WHITE);
|
||||
textView.setText("Click the map to calculate the distance");
|
||||
textView.setPadding(padding, padding, padding, padding);
|
||||
|
||||
return textView;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupActionBar() {
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
@@ -16,7 +15,6 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class InfoWindowActivity extends AppCompatActivity implements OnMapReadyCallback, MapboxMap.OnInfoWindowCloseListener, MapboxMap.OnMapLongClickListener, MapboxMap.OnInfoWindowClickListener, MapboxMap.OnInfoWindowLongClickListener {
|
||||
@@ -61,6 +59,12 @@ public class InfoWindowActivity extends AppCompatActivity implements OnMapReadyC
|
||||
.snippet("E St NW with 17th St NW")
|
||||
.position(new LatLng(38.8954236, -77.0394623)));
|
||||
|
||||
mapboxMap.addMarker(new MarkerOptions().title("The Ellipse").position(new LatLng(38.89393, -77.03654)));
|
||||
|
||||
mapboxMap.addMarker(new MarkerOptions().position(new LatLng(38.89596, -77.03434)));
|
||||
|
||||
mapboxMap.addMarker(new MarkerOptions().snippet("Lafayette Square").position(new LatLng(38.89949, -77.03656)));
|
||||
|
||||
Marker marker = mapboxMap.addMarker(new MarkerOptions()
|
||||
.title("White House")
|
||||
.snippet("The official residence and principal workplace of the President of the United States, located at 1600 Pennsylvania Avenue NW in Washington, D.C. It has been the residence of every U.S. president since John Adams in 1800.")
|
||||
@@ -82,6 +86,10 @@ public class InfoWindowActivity extends AppCompatActivity implements OnMapReadyC
|
||||
mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(allowConcurrentInfoWindow);
|
||||
}
|
||||
|
||||
private void toggleDeselectMarkersOnTap(boolean deselectMarkersOnTap) {
|
||||
mapboxMap.getUiSettings().setDeselectMarkersOnTap(deselectMarkersOnTap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInfoWindowClick(@NonNull Marker marker) {
|
||||
Toast.makeText(getApplicationContext(), "OnClick: " + marker.getTitle(), Toast.LENGTH_LONG).show();
|
||||
@@ -157,6 +165,10 @@ public class InfoWindowActivity extends AppCompatActivity implements OnMapReadyC
|
||||
toggleConcurrentInfoWindow(!item.isChecked());
|
||||
item.setChecked(!item.isChecked());
|
||||
return true;
|
||||
case R.id.action_toggle_deselect_markers_on_tap:
|
||||
toggleDeselectMarkersOnTap(!item.isChecked());
|
||||
item.setChecked(!item.isChecked());
|
||||
return true;
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,467 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.navigation;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.PointF;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerView;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.location.LocationListener;
|
||||
import com.mapbox.mapboxsdk.location.LocationServices;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.model.annotations.PulseMarkerView;
|
||||
import com.mapbox.mapboxsdk.testapp.model.annotations.PulseMarkerViewOptions;
|
||||
import com.mapbox.services.commons.ServicesException;
|
||||
import com.mapbox.services.commons.models.Position;
|
||||
import com.mapbox.services.geocoding.v5.GeocodingCriteria;
|
||||
import com.mapbox.services.geocoding.v5.MapboxGeocoding;
|
||||
import com.mapbox.services.geocoding.v5.models.GeocodingFeature;
|
||||
import com.mapbox.services.geocoding.v5.models.GeocodingResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Sample Activity to show a typical location picker use case
|
||||
*/
|
||||
public class LocationPickerActivity extends AppCompatActivity {
|
||||
private static final String TAG = "LocationPickerActivity";
|
||||
private static final int REQUEST_PERMISSIONS = 101;
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
private ImageView dropPinView;
|
||||
private Marker addressPin;
|
||||
private ImageButton clearDisplayViewButton;
|
||||
private MarkerView userMarker;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_location_picker);
|
||||
|
||||
setupActionBar();
|
||||
|
||||
//Initialize map as normal
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
//Create ui elements
|
||||
createDropPin();
|
||||
createSelectLocationButton();
|
||||
createClearSelectionButton();
|
||||
|
||||
mapView.getMapAsync(new OnMapReadyCallback() {
|
||||
@Override
|
||||
public void onMapReady(MapboxMap map) {
|
||||
//Store for later
|
||||
mapboxMap = map;
|
||||
|
||||
//Add user marker
|
||||
mapboxMap.getMarkerViewManager().addMarkerViewAdapter(new PulseMarkerViewAdapter(LocationPickerActivity.this));
|
||||
userMarker = createCustomUserMarker(new LatLng(0, 0));
|
||||
|
||||
//Fix the focal point to the center of the map
|
||||
PointF focalPoint = new PointF((mapView.getX() + mapView.getWidth() / 2), (mapView.getY() + mapView.getHeight() / 2));
|
||||
mapboxMap.getUiSettings().setFocalPoint(focalPoint);
|
||||
|
||||
//Track camera updates to animate the user location views
|
||||
trackUserLocationView(userMarker);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
|
||||
//Check permissions
|
||||
if (arePermissionsGranted()) {
|
||||
mapView.getMapAsync(new OnMapReadyCallback() {
|
||||
|
||||
@Override
|
||||
public void onMapReady(final MapboxMap mapboxMap) {
|
||||
//Get the user's location
|
||||
final LocationServices locationServices = LocationServices.getLocationServices(getApplicationContext());
|
||||
|
||||
Location location = locationServices.getLastLocation();
|
||||
if (location != null) {
|
||||
zoomInOn(location);
|
||||
userMarker.setPosition(new LatLng(location));
|
||||
} else {
|
||||
final ProgressDialog loadingDialog = ProgressDialog.show(LocationPickerActivity.this, "Loading", "Getting user location", false);
|
||||
locationServices.addLocationListener(new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(@Nullable Location location) {
|
||||
//Move the camera to the user
|
||||
if (location != null) {
|
||||
zoomInOn(location);
|
||||
userMarker.setPosition(new LatLng(location));
|
||||
locationServices.removeLocationListener(this);
|
||||
loadingDialog.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
locationServices.toggleGPS(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void zoomInOn(Location location) {
|
||||
//Move the camera to the user
|
||||
if (location != null) {
|
||||
mapboxMap.setCameraPosition(new CameraPosition.Builder()
|
||||
.target(new LatLng(location))
|
||||
.zoom(16)
|
||||
.bearing(0)
|
||||
.tilt(0)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tracks the camera to animate the marker when overlapping with the picker.
|
||||
* Makes sure the marker actually points to the user's position by tracking it.
|
||||
*/
|
||||
private void trackUserLocationView(final MarkerView markerView) {
|
||||
final float circleDiameterSize = getResources().getDimension(R.dimen.circle_size);
|
||||
|
||||
//Track camera changes to check for overlap
|
||||
mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
|
||||
|
||||
private Animation pulseAnimation;
|
||||
|
||||
@Override
|
||||
public void onCameraChange(CameraPosition position) {
|
||||
if (markerView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Make drop pin visible, if it wasn't already
|
||||
showDropPin();
|
||||
|
||||
//Get the distance from the tip of the location picker to the MarkerView
|
||||
double distance = getLocationPickerLocation().distanceTo(markerView.getPosition());
|
||||
|
||||
//If closeby, animate, otherwise, stop animation
|
||||
View view = mapboxMap.getMarkerViewManager().getView(markerView);
|
||||
if (view != null) {
|
||||
View backgroundView = view.findViewById(R.id.background_imageview);
|
||||
if (pulseAnimation == null && distance < 0.5f * circleDiameterSize) {
|
||||
pulseAnimation = AnimationUtils.loadAnimation(LocationPickerActivity.this, R.anim.pulse);
|
||||
pulseAnimation.setRepeatCount(Animation.INFINITE);
|
||||
pulseAnimation.setRepeatMode(Animation.RESTART);
|
||||
backgroundView.startAnimation(pulseAnimation);
|
||||
} else if (pulseAnimation != null && distance >= 0.5f * circleDiameterSize) {
|
||||
backgroundView.clearAnimation();
|
||||
pulseAnimation = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Track location updates to move the user marker
|
||||
LocationServices.getLocationServices(getApplicationContext()).addLocationListener(new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
if (location != null && markerView != null) {
|
||||
markerView.setPosition(new LatLng(location));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private MarkerView createCustomUserMarker(LatLng markerPosition) {
|
||||
return mapboxMap.addMarker(new PulseMarkerViewOptions()
|
||||
.icon(IconFactory.getInstance(getApplicationContext()).fromResource(R.drawable.ic_my_location_24dp))
|
||||
.position(markerPosition)
|
||||
);
|
||||
}
|
||||
|
||||
private void createClearSelectionButton() {
|
||||
clearDisplayViewButton = (ImageButton) findViewById(R.id.clearDisplayViewButton);
|
||||
clearDisplayViewButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
removeAddressPin();
|
||||
hide(clearDisplayViewButton);
|
||||
showDropPin();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createSelectLocationButton() {
|
||||
Button selectLocationButton = (Button) findViewById(R.id.selectLocationButton);
|
||||
//noinspection ConstantConditions
|
||||
selectLocationButton.setOnClickListener(
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Log.i(TAG, "Location Selected!");
|
||||
if (mapboxMap != null) {
|
||||
//Control button's state
|
||||
clearDisplayViewButton.setVisibility(View.VISIBLE);
|
||||
dropPinView.setVisibility(View.INVISIBLE);
|
||||
|
||||
//Get position for the drop pin
|
||||
LatLng position = getLocationPickerLocation();
|
||||
|
||||
//Show the address pin (result)
|
||||
showAddressPin(position);
|
||||
|
||||
//Get the address for that location and update the marker
|
||||
geocode(position, new GeocodeCallbacks() {
|
||||
@Override
|
||||
public void onResult(String result) {
|
||||
updateAddressPin(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable failure) {
|
||||
showFeedbackMessage("Could not retrieve address: " + failure.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void createDropPin() {
|
||||
float density = getResources().getDisplayMetrics().density;
|
||||
|
||||
dropPinView = new ImageView(this);
|
||||
dropPinView.setImageResource(R.drawable.ic_droppin_24dp);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
|
||||
params.bottomMargin = (int) (12 * density);
|
||||
dropPinView.setLayoutParams(params);
|
||||
|
||||
mapView.addView(dropPinView);
|
||||
}
|
||||
|
||||
private void showDropPin() {
|
||||
if (dropPinView != null && dropPinView.getVisibility() != View.VISIBLE) {
|
||||
dropPinView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void hide(View view) {
|
||||
if (view != null) {
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupActionBar() {
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get address for the given location
|
||||
*/
|
||||
private void geocode(LatLng point, final GeocodeCallbacks callbacks) {
|
||||
try {
|
||||
//Create Geocoding client
|
||||
MapboxGeocoding client = new MapboxGeocoding.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setCoordinates(Position.fromCoordinates(point.getLongitude(), point.getLatitude()))
|
||||
.setType(GeocodingCriteria.TYPE_ADDRESS)
|
||||
.build();
|
||||
|
||||
//Place the request
|
||||
client.enqueueCall(new Callback<GeocodingResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {
|
||||
|
||||
List<GeocodingFeature> results = response.body().getFeatures();
|
||||
String address = null;
|
||||
if (results.size() > 0) {
|
||||
GeocodingFeature feature = results.get(0);
|
||||
address = feature.getAddress() + " " + feature.getText();
|
||||
Log.i(TAG, "address " + address);
|
||||
} else {
|
||||
showFeedbackMessage("No results for search.");
|
||||
}
|
||||
|
||||
callbacks.onResult(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<GeocodingResponse> call, Throwable t) {
|
||||
Log.e(TAG, "Geocoding Failure: " + t.getMessage());
|
||||
callbacks.onFailure(t);
|
||||
}
|
||||
});
|
||||
} catch (ServicesException e) {
|
||||
Log.e(TAG, "Error geocoding: " + e.toString());
|
||||
callbacks.onFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
private LatLng getLocationPickerLocation() {
|
||||
return mapboxMap.getProjection().fromScreenLocation(
|
||||
new PointF(dropPinView.getLeft() + (dropPinView.getWidth() / 2), dropPinView.getBottom())
|
||||
);
|
||||
}
|
||||
|
||||
private Marker showAddressPin(LatLng position) {
|
||||
if (addressPin != null) {
|
||||
//Remove previous pin
|
||||
removeAddressPin();
|
||||
}
|
||||
|
||||
//Create new one
|
||||
addressPin = mapboxMap.addMarker(new MarkerViewOptions().title("Loading address...").position(position));
|
||||
mapboxMap.selectMarker(addressPin);
|
||||
return addressPin;
|
||||
}
|
||||
|
||||
private void removeAddressPin() {
|
||||
if (mapboxMap != null && addressPin != null) {
|
||||
mapboxMap.removeMarker(addressPin);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAddressPin(@Nullable String address) {
|
||||
if (addressPin != null) {
|
||||
addressPin.setTitle(address == null ? "No address found" : address);
|
||||
}
|
||||
}
|
||||
|
||||
private void showFeedbackMessage(String message) {
|
||||
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private boolean arePermissionsGranted() {
|
||||
if (Build.VERSION.SDK_INT >= 23 &&
|
||||
checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
|
||||
checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
Log.i(TAG, "Requesting permissions");
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSIONS);
|
||||
return false;
|
||||
}
|
||||
Log.i(TAG, "Permissions already granted");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom MarkerViewAdapter for the pulsing marker
|
||||
*/
|
||||
private static class PulseMarkerViewAdapter extends MapboxMap.MarkerViewAdapter<PulseMarkerView> {
|
||||
|
||||
private LayoutInflater inflater;
|
||||
|
||||
public PulseMarkerViewAdapter(@NonNull Context context) {
|
||||
super(context);
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View getView(@NonNull PulseMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||
ViewHolder viewHolder;
|
||||
if (convertView == null) {
|
||||
viewHolder = new ViewHolder();
|
||||
convertView = inflater.inflate(R.layout.view_pulse_marker, parent, false);
|
||||
viewHolder.foregroundImageView = (ImageView) convertView.findViewById(R.id.foreground_imageView);
|
||||
viewHolder.backgroundImageView = (ImageView) convertView.findViewById(R.id.background_imageview);
|
||||
convertView.setTag(viewHolder);
|
||||
}
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
ImageView foregroundImageView;
|
||||
ImageView backgroundImageView;
|
||||
}
|
||||
}
|
||||
|
||||
private interface GeocodeCallbacks {
|
||||
void onResult(String result);
|
||||
|
||||
void onFailure(Throwable failure);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.userlocation;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
@@ -26,6 +31,8 @@ import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
public class MyLocationDrawableActivity extends AppCompatActivity implements LocationListener {
|
||||
|
||||
private static final int PERMISSIONS_LOCATION = 0;
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private Location location;
|
||||
@@ -45,20 +52,13 @@ public class MyLocationDrawableActivity extends AppCompatActivity implements Loc
|
||||
}
|
||||
|
||||
findViewById(R.id.progress).setVisibility(View.GONE);
|
||||
location = LocationServices.getLocationServices(this).getLastLocation();
|
||||
|
||||
MapboxMapOptions mapboxMapOptions = new MapboxMapOptions();
|
||||
mapboxMapOptions.accessToken(getString(R.string.mapbox_access_token));
|
||||
mapboxMapOptions.styleUrl(Style.MAPBOX_STREETS);
|
||||
mapboxMapOptions.locationEnabled(true);
|
||||
mapboxMapOptions.camera(new CameraPosition.Builder()
|
||||
.target(location != null ? new LatLng(location) : new LatLng(0, 0))
|
||||
.zoom(11)
|
||||
.tilt(25)
|
||||
.build());
|
||||
|
||||
mapboxMapOptions.myLocationForegroundDrawables(ContextCompat.getDrawable(this, R.drawable.ic_chelsea),
|
||||
ContextCompat.getDrawable(this, R.drawable.ic_chelsea));
|
||||
// configure MyLocationView drawables
|
||||
mapboxMapOptions.myLocationForegroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_chelsea));
|
||||
mapboxMapOptions.myLocationBackgroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_arsenal));
|
||||
mapboxMapOptions.myLocationForegroundTintColor(Color.GREEN);
|
||||
mapboxMapOptions.myLocationBackgroundTintColor(Color.YELLOW);
|
||||
@@ -78,17 +78,53 @@ public class MyLocationDrawableActivity extends AppCompatActivity implements Loc
|
||||
@Override
|
||||
public void onMapReady(MapboxMap map) {
|
||||
mapboxMap = map;
|
||||
toggleGps(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
LocationServices.getLocationServices(this).addLocationListener(this);
|
||||
public void toggleGps(boolean enableGps) {
|
||||
if (enableGps) {
|
||||
if ((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) ||
|
||||
(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
|
||||
} else {
|
||||
enableLocation(true);
|
||||
}
|
||||
} else {
|
||||
enableLocation(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void enableLocation(boolean enabled) {
|
||||
if (enabled) {
|
||||
mapboxMap.setMyLocationEnabled(true);
|
||||
Location location = mapboxMap.getMyLocation();
|
||||
if (location != null) {
|
||||
onLocationChanged(location);
|
||||
}else{
|
||||
LocationServices.getLocationServices(this).addLocationListener(this);
|
||||
}
|
||||
} else {
|
||||
mapboxMap.setMyLocationEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case PERMISSIONS_LOCATION: {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
enableLocation(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
if (mapboxMap != null && firstRun) {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 10));
|
||||
firstRun = false;
|
||||
if (mapboxMap != null) {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 14));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.userlocation;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
@@ -33,6 +38,7 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
|
||||
private MapboxMap mMapboxMap;
|
||||
private Spinner mLocationSpinner, mBearingSpinner;
|
||||
private Location mLocation;
|
||||
private static final int PERMISSIONS_LOCATION = 0;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -57,8 +63,9 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
|
||||
mMapboxMap = mapboxMap;
|
||||
|
||||
// disable dismissal when a gesture occurs
|
||||
mMapboxMap.getTrackingSettings().setDismissLocationTrackingOnGesture(false);
|
||||
mMapboxMap.getTrackingSettings().setDismissBearingTrackingOnGesture(false);
|
||||
TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
|
||||
trackingSettings.setDismissLocationTrackingOnGesture(false);
|
||||
trackingSettings.setDismissBearingTrackingOnGesture(false);
|
||||
|
||||
mapboxMap.setOnMyLocationChangeListener(MyLocationTrackingModeActivity.this);
|
||||
|
||||
@@ -96,15 +103,48 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
mLocation = LocationServices.getLocationServices(MyLocationTrackingModeActivity.this).getLastLocation();
|
||||
if(mLocation!=null){
|
||||
setInitialPosition(new LatLng(mLocation));
|
||||
}
|
||||
toggleGps(!mapboxMap.isMyLocationEnabled());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void toggleGps(boolean enableGps) {
|
||||
if (enableGps) {
|
||||
if ((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) ||
|
||||
(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
|
||||
} else {
|
||||
enableLocation(true);
|
||||
}
|
||||
} else {
|
||||
enableLocation(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void enableLocation(boolean enabled) {
|
||||
if (enabled) {
|
||||
mMapboxMap.setMyLocationEnabled(true);
|
||||
Location location = mMapboxMap.getMyLocation();
|
||||
if (location != null) {
|
||||
setInitialPosition(new LatLng(location));
|
||||
}
|
||||
} else {
|
||||
mMapboxMap.setMyLocationEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case PERMISSIONS_LOCATION: {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
enableLocation(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setInitialPosition(LatLng latLng){
|
||||
mMapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14));
|
||||
mMapboxMap.setMyLocationEnabled(true);
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.os.Parcelable;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerView;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
|
||||
public class CountryMarkerViewOptions extends BaseMarkerViewOptions<CountryMarkerView, CountryMarkerViewOptions> {
|
||||
@@ -23,8 +24,10 @@ public class CountryMarkerViewOptions extends BaseMarkerViewOptions<CountryMarke
|
||||
title(in.readString());
|
||||
flat(in.readByte() != 0);
|
||||
anchor(in.readFloat(), in.readFloat());
|
||||
selected = in.readByte() != 0;
|
||||
infoWindowAnchor(in.readFloat(), in.readFloat());
|
||||
rotation(in.readFloat());
|
||||
visible(in.readByte() != 0);
|
||||
alpha(in.readFloat());
|
||||
if (in.readByte() != 0) {
|
||||
// this means we have an icon
|
||||
String iconId = in.readString();
|
||||
@@ -56,8 +59,9 @@ public class CountryMarkerViewOptions extends BaseMarkerViewOptions<CountryMarke
|
||||
out.writeFloat(getAnchorV());
|
||||
out.writeFloat(getInfoWindowAnchorU());
|
||||
out.writeFloat(getInfoWindowAnchorV());
|
||||
out.writeByte((byte) (selected ? 1 : 0));
|
||||
out.writeFloat(getRotation());
|
||||
out.writeByte((byte) (isVisible() ? 1 : 0));
|
||||
out.writeFloat(getAlpha());
|
||||
Icon icon = getIcon();
|
||||
out.writeByte((byte) (icon != null ? 1 : 0));
|
||||
if (icon != null) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mapbox.mapboxsdk.testapp.model.annotations;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerView;
|
||||
|
||||
public class PulseMarkerView extends MarkerView {
|
||||
|
||||
public PulseMarkerView(BaseMarkerViewOptions baseMarkerViewOptions) {
|
||||
super(baseMarkerViewOptions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.mapbox.mapboxsdk.testapp.model.annotations;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
|
||||
public class PulseMarkerViewOptions extends BaseMarkerViewOptions<PulseMarkerView, PulseMarkerViewOptions> {
|
||||
|
||||
public PulseMarkerViewOptions() {
|
||||
}
|
||||
|
||||
protected PulseMarkerViewOptions(Parcel in) {
|
||||
position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
|
||||
snippet(in.readString());
|
||||
title(in.readString());
|
||||
flat(in.readByte() != 0);
|
||||
anchor(in.readFloat(), in.readFloat());
|
||||
selected = in.readByte() != 0;
|
||||
rotation(in.readFloat());
|
||||
if (in.readByte() != 0) {
|
||||
// this means we have an icon
|
||||
String iconId = in.readString();
|
||||
Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
|
||||
Icon icon = IconFactory.recreate(iconId, iconBitmap);
|
||||
icon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PulseMarkerViewOptions getThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeParcelable(getPosition(), flags);
|
||||
out.writeString(getSnippet());
|
||||
out.writeString(getTitle());
|
||||
out.writeByte((byte) (isFlat() ? 1 : 0));
|
||||
out.writeFloat(getAnchorU());
|
||||
out.writeFloat(getAnchorV());
|
||||
out.writeFloat(getInfoWindowAnchorU());
|
||||
out.writeFloat(getInfoWindowAnchorV());
|
||||
out.writeByte((byte) (selected ? 1 : 0));
|
||||
out.writeFloat(getRotation());
|
||||
Icon icon = getIcon();
|
||||
out.writeByte((byte) (icon != null ? 1 : 0));
|
||||
if (icon != null) {
|
||||
out.writeString(getIcon().getId());
|
||||
out.writeParcelable(getIcon().getBitmap(), flags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PulseMarkerView getMarker() {
|
||||
return new PulseMarkerView(this);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<CountryMarkerViewOptions> CREATOR
|
||||
= new Parcelable.Creator<CountryMarkerViewOptions>() {
|
||||
public CountryMarkerViewOptions createFromParcel(Parcel in) {
|
||||
return new CountryMarkerViewOptions(in);
|
||||
}
|
||||
|
||||
public CountryMarkerViewOptions[] newArray(int size) {
|
||||
return new CountryMarkerViewOptions[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import android.os.Parcelable;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerView;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
|
||||
public class TextMarkerViewOptions extends BaseMarkerViewOptions<TextMarkerView, TextMarkerViewOptions> {
|
||||
@@ -24,6 +25,8 @@ public class TextMarkerViewOptions extends BaseMarkerViewOptions<TextMarkerView,
|
||||
anchor(in.readFloat(), in.readFloat());
|
||||
infoWindowAnchor(in.readFloat(), in.readFloat());
|
||||
rotation(in.readFloat());
|
||||
visible(in.readByte() != 0);
|
||||
alpha(in.readFloat());
|
||||
if (in.readByte() != 0) {
|
||||
// this means we have an icon
|
||||
String iconId = in.readString();
|
||||
@@ -55,6 +58,8 @@ public class TextMarkerViewOptions extends BaseMarkerViewOptions<TextMarkerView,
|
||||
out.writeFloat(getInfoWindowAnchorU());
|
||||
out.writeFloat(getInfoWindowAnchorV());
|
||||
out.writeFloat(getRotation());
|
||||
out.writeByte((byte) (isVisible() ? 1 : 0));
|
||||
out.writeFloat(alpha);
|
||||
Icon icon = getIcon();
|
||||
out.writeByte((byte) (icon != null ? 1 : 0));
|
||||
if (icon != null) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/decelerate_interpolator">
|
||||
|
||||
<scale
|
||||
android:duration="1000"
|
||||
android:fromXScale="1"
|
||||
android:fromYScale="1"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:repeatCount="infinite"
|
||||
android:repeatMode="restart"
|
||||
android:toXScale="1.8"
|
||||
android:toYScale="1.8"/>
|
||||
|
||||
<set android:startOffset="200">
|
||||
<alpha
|
||||
android:duration="800"
|
||||
android:fromAlpha="1.0"
|
||||
android:repeatCount="infinite"
|
||||
android:repeatMode="restart"
|
||||
android:toAlpha="0.0"/>
|
||||
</set>
|
||||
</set>
|
||||
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<solid
|
||||
android:color="@color/mapbox_blue"/>
|
||||
|
||||
<size
|
||||
android:width="@dimen/circle_size"
|
||||
android:height="@dimen/circle_size"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M18.92,6.01C18.72,5.42 18.16,5 17.5,5h-11c-0.66,0 -1.21,0.42 -1.42,1.01L3,12v8c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h12v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-8l-2.08,-5.99zM6.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,13 6.5,13s1.5,0.67 1.5,1.5S7.33,16 6.5,16zM17.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM5,11l1.5,-4.5h11L19,11L5,11z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M13.49,5.48c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM9.89,19.38l1,-4.4 2.1,2v6h2v-7.5l-2.1,-2 0.6,-3c1.3,1.5 3.3,2.5 5.5,2.5v-2c-1.9,0 -3.5,-1 -4.3,-2.4l-1,-1.6c-0.4,-0.6 -1,-1 -1.7,-1 -0.3,0 -0.5,0.1 -0.8,0.1l-5.2,2.2v4.7h2v-3.4l1.8,-0.7 -1.6,8.1 -4.9,-1 -0.4,2 7,1.4z"/>
|
||||
</vector>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
@@ -16,7 +16,10 @@
|
||||
android:id="@+id/mapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/toolbar"
|
||||
app:center_latitude="51.502615"
|
||||
app:center_longitude="4.972326"
|
||||
app:style_url="@string/style_light"
|
||||
android:layout_below="@id/toolbar" />
|
||||
app:zoom="6" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/primary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||
|
||||
<com.mapbox.mapboxsdk.maps.MapView
|
||||
android:id="@+id/mapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:style_url="@string/style_mapbox_streets"
|
||||
app:center_latitude="47.798202"
|
||||
app:center_longitude="7.573781"
|
||||
app:zoom="4" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/primary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||
|
||||
<com.mapbox.mapboxsdk.maps.MapView
|
||||
android:id="@+id/mapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/toolbar"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/clearDisplayViewButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_clear_24dp"
|
||||
android:background="@color/accent"
|
||||
android:visibility="gone"
|
||||
android:layout_marginLeft="@dimen/full_button_margin"
|
||||
android:layout_above="@+id/selectLocationButton"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/selectLocationButton"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/full_button_margin"
|
||||
android:background="@color/primary"
|
||||
android:text="@string/navigation_select_location_button_text"
|
||||
android:textColor="@android:color/white"
|
||||
android:layout_alignParentBottom="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/primary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:textSize="20sp"
|
||||
android:textColor="#FFFFFF"
|
||||
android:text="Scaling in the View Marker API" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textview_factor"
|
||||
android:layout_alignBottom="@+id/seekbar_factor"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Scale: 1" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekbar_factor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_marginLeft="56dp"
|
||||
android:progress="0" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
<com.mapbox.mapboxsdk.maps.MapView
|
||||
android:id="@id/mapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/toolbar"
|
||||
app:center_latitude="38.907192"
|
||||
app:center_longitude="-77.036871"
|
||||
app:style_url="@string/style_mapbox_streets"
|
||||
app:zoom="12" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/foreground_imageView"
|
||||
android:layout_width="@dimen/circle_size"
|
||||
android:layout_height="@dimen/circle_size"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_circle"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/background_imageview"
|
||||
android:layout_width="@dimen/circle_size"
|
||||
android:layout_height="@dimen/circle_size"
|
||||
android:layout_gravity="center"
|
||||
android:alpha="0.5"
|
||||
android:src="@drawable/ic_circle"/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -8,6 +8,12 @@
|
||||
android:id="@+id/action_toggle_concurrent_infowindow"
|
||||
app:showAsAction="never"
|
||||
android:checkable="true"/>
|
||||
<item
|
||||
android:title="@string/menuitem_title_deselect_markers_on_tap"
|
||||
android:id="@+id/action_toggle_deselect_markers_on_tap"
|
||||
app:showAsAction="never"
|
||||
android:checkable="true"
|
||||
android:checked="true"/>
|
||||
</group>
|
||||
|
||||
</menu>
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="circle_size">24dp</dimen>
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
<dimen name="full_button_margin">8dp</dimen>
|
||||
<dimen name="attr_margin">10dp</dimen>
|
||||
<dimen name="coordinatebounds_margin">32dp</dimen>
|
||||
<dimen name="map_padding_left">96dp</dimen>
|
||||
|
||||
@@ -18,10 +18,12 @@
|
||||
<string name="activity_polygon">Polygon</string>
|
||||
<string name="activity_press_for_marker">Press Map For Marker</string>
|
||||
<string name="activity_view_marker">View Marker API</string>
|
||||
<string name="activity_view_marker_scale">Scaling in the View Marker API</string>
|
||||
|
||||
<!-- InfoWindow-->
|
||||
<string name="activity_info_window">Standard InfoWindow example</string>
|
||||
<string name="activity_infowindow_adapter">Custom InfoWindow Adapter</string>
|
||||
<string name="activity_info_window">Standard InfoWindow</string>
|
||||
<string name="activity_infowindow_adapter">Custom InfoWindow</string>
|
||||
<string name="activity_dynamic_infowindow_adapter">Custom Dynamic InfoWindow</string>
|
||||
|
||||
<!-- Camera -->
|
||||
<string name="activity_camera_animation_types">Animation Types</string>
|
||||
@@ -34,6 +36,9 @@
|
||||
<string name="activity_directions">Directions</string>
|
||||
<string name="activity_geocoder">Geocoder</string>
|
||||
|
||||
<!-- Navigation -->
|
||||
<string name="activity_location_picker">Location Picker</string>
|
||||
|
||||
<!-- Other -->
|
||||
<string name="activity_double_map">Double Map Activity</string>
|
||||
<string name="activity_back_to_map">Back to map activity</string>
|
||||
@@ -80,8 +85,12 @@
|
||||
<string name="description_doublemap">2 maps in a view hierarchy</string>
|
||||
<string name="description_back_to_map">Restart map view after temporarily leaving to another activity</string>
|
||||
<string name="description_view_marker">Use an Android SDK View as marker</string>
|
||||
<string name="description_view_marker_scale">Scale a View Marker</string>
|
||||
<string name="description_dynamic_info_window_adapter">Learn how to create a dynamic custom InfoWindow</string>
|
||||
<string name="description_location_picker">Use a fixed Marker to select your location</string>
|
||||
|
||||
<string name="menuitem_title_concurrent_infowindow">Concurrent Open InfoWindows</string>r
|
||||
<string name="menuitem_title_concurrent_infowindow">Concurrent Open InfoWindows</string>
|
||||
<string name="menuitem_title_deselect_markers_on_tap">Deselect Markers On Tap</string>
|
||||
<string name="menuitem_title_tracking_mode_dismiss_on_gesture">Dismiss location tracking on gesture</string>
|
||||
<string name="menuitem_title_bearing_mode_dismiss_on_gesture">Dismiss bearing tracking on gesture</string>
|
||||
<string name="menuitem_title_reset">Reset</string>
|
||||
@@ -98,6 +107,7 @@
|
||||
<string name="category_maplayout">Map Layout</string>
|
||||
<string name="category_offline">Offline</string>
|
||||
<string name="category_userlocation">User Location</string>
|
||||
<string name="category_navigation">Navigation</string>
|
||||
|
||||
<string name="action_visible_bounds_explanation">Center map around 2 markers</string>
|
||||
<string name="action_remove_polylines">Remove polylines</string>
|
||||
@@ -159,4 +169,6 @@
|
||||
<string name="dynamic_marker_arsenal_title">Arsenal</string>
|
||||
<string name="dynamic_marker_arsenal_snippet">Emirates Stadium</string>
|
||||
|
||||
<string name="navigation_select_location_button_text">Select Location!</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -7,7 +7,7 @@ buildscript {
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.1.0'
|
||||
classpath 'com.android.tools.build:gradle:2.1.2'
|
||||
classpath 'com.github.JakeWharton:sdk-manager-plugin:220bf7a88a7072df3ed16dc8466fb144f2817070'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||