Merge remote-tracking branch 'origin/release-android-v4.1.0'

This commit is contained in:
John Firebaugh
2016-06-29 17:03:00 -07:00
56 changed files with 1853 additions and 250 deletions

View File

@@ -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))

View File

@@ -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

View File

@@ -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();

View File

@@ -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.
*

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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
*/

View File

@@ -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();
}

View File

@@ -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
*/

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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
*

View File

@@ -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();
}
}

View File

@@ -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);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -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"

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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)
);
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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());
}
}
/*

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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];
}
};
}

View File

@@ -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) {

View File

@@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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