diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/FeatureOverviewActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/FeatureOverviewActivity.java index 1be6e6ec5..1c8932779 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/FeatureOverviewActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/FeatureOverviewActivity.java @@ -26,9 +26,9 @@ import android.widget.TextView; import android.widget.Toast; +import com.mapbox.android.core.permissions.PermissionsListener; +import com.mapbox.android.core.permissions.PermissionsManager; import com.mapbox.mapboxsdk.plugins.testapp.R; -import com.mapbox.services.android.telemetry.permissions.PermissionsListener; -import com.mapbox.services.android.telemetry.permissions.PermissionsManager; import java.util.ArrayList; import java.util.Arrays; diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java index af458aa1e..e2f5eca9b 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java @@ -9,11 +9,11 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.mapboxsdk.plugins.locationlayer.CompassListener; -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin; +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.mapboxsdk.plugins.testapp.R; import com.mapbox.services.android.telemetry.location.LocationEngine; -import com.mapbox.services.android.telemetry.location.LostLocationEngine; +import com.mapbox.services.android.telemetry.location.LocationEngineProvider; import butterknife.BindView; import butterknife.ButterKnife; @@ -39,7 +39,7 @@ protected void onCreate(Bundle savedInstanceState) { @Override public void onMapReady(final MapboxMap mapboxMap) { - LocationEngine locationEngine = new LostLocationEngine(this); + LocationEngine locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable(); locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine); locationLayerPlugin.setRenderMode(RenderMode.COMPASS); locationLayerPlugin.addCompassListener(new CompassListener() { diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerMapChangeActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerMapChangeActivity.java index baca6fbc6..77ed87d0d 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerMapChangeActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerMapChangeActivity.java @@ -9,13 +9,13 @@ import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin; +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.mapboxsdk.plugins.testapp.R; import com.mapbox.mapboxsdk.plugins.testapp.Utils; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEnginePriority; -import com.mapbox.services.android.telemetry.location.LostLocationEngine; +import com.mapbox.services.android.telemetry.location.LocationEngineProvider; import butterknife.BindView; import butterknife.ButterKnife; @@ -48,11 +48,12 @@ protected void onCreate(Bundle savedInstanceState) { @Override public void onMapReady(MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; - locationEngine = LostLocationEngine.getLocationEngine(this); + locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable(); locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY); locationEngine.activate(); locationPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine); locationPlugin.setRenderMode(RenderMode.COMPASS); + getLifecycle().addObserver(locationPlugin); } @OnClick(R.id.fabStyles) diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java index 2b778acae..03bc69c82 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java @@ -19,15 +19,17 @@ import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; +import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerOptions; import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin; -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode; +import com.mapbox.mapboxsdk.plugins.locationlayer.OnCameraTrackingChangedListener; import com.mapbox.mapboxsdk.plugins.locationlayer.OnLocationLayerClickListener; +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode; +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.mapboxsdk.plugins.testapp.R; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEngineListener; import com.mapbox.services.android.telemetry.location.LocationEnginePriority; -import com.mapbox.services.android.telemetry.location.LostLocationEngine; +import com.mapbox.services.android.telemetry.location.LocationEngineProvider; import java.util.ArrayList; import java.util.List; @@ -37,7 +39,7 @@ import butterknife.OnClick; public class LocationLayerModesActivity extends AppCompatActivity implements OnMapReadyCallback, - LocationEngineListener, OnLocationLayerClickListener { + LocationEngineListener, OnLocationLayerClickListener, OnCameraTrackingChangedListener { @BindView(R.id.map_view) MapView mapView; @@ -86,12 +88,16 @@ public void locationModeCompass(View view) { @Override public void onMapReady(MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; - locationEngine = new LostLocationEngine(this); + locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable(); locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY); locationEngine.addLocationEngineListener(this); locationEngine.activate(); - locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine); + LocationLayerOptions options = LocationLayerOptions.builder(this) + .padding(new int[] {0, 650, 0, 0}) + .build(); + locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine, options); locationLayerPlugin.addOnLocationClickListener(this); + locationLayerPlugin.addOnCameraTrackingChangedListener(this); getLifecycle().addObserver(locationLayerPlugin); } @@ -261,4 +267,14 @@ private void showTrackingListDialog() { }); listPopup.show(); } + + @Override + public void onCameraTrackingDismissed() { + locationTrackingBtn.setText("None"); + } + + @Override + public void onCameraTrackingChanged(int currentMode) { + // do nothing + } } \ No newline at end of file diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/ManualLocationUpdatesActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/ManualLocationUpdatesActivity.java index 8bab874b0..4ff8fb234 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/ManualLocationUpdatesActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/ManualLocationUpdatesActivity.java @@ -7,17 +7,17 @@ import android.support.v7.app.AppCompatActivity; import android.view.View; +import com.mapbox.android.core.location.LocationEngine; +import com.mapbox.android.core.location.LocationEngineListener; +import com.mapbox.android.core.location.LocationEnginePriority; +import com.mapbox.android.core.location.LocationEngineProvider; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin; +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.mapboxsdk.plugins.testapp.R; import com.mapbox.mapboxsdk.plugins.testapp.Utils; -import com.mapbox.services.android.telemetry.location.LocationEngine; -import com.mapbox.services.android.telemetry.location.LocationEngineListener; -import com.mapbox.services.android.telemetry.location.LocationEnginePriority; -import com.mapbox.services.android.telemetry.location.LostLocationEngine; import butterknife.BindView; import butterknife.ButterKnife; @@ -66,7 +66,7 @@ public void manualLocationChangeFabClick(View view) { @SuppressWarnings( {"MissingPermission"}) public void onMapReady(MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; - locationEngine = new LostLocationEngine(this); + locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable(); locationEngine.addLocationEngineListener(this); locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY); locationEngine.activate(); diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 08a4385e9..bc08b116d 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -8,7 +8,7 @@ ext { ] version = [ - mapboxMapSdk : '5.5.0', + mapboxMapSdk : '6.0.0-20180301.094208-178', mapboxGeocoding : '3.0.0-beta.3', mapboxGeoJson : '3.0.0-beta.3', mapboxServices : '2.2.9', diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 860ae1ef2..8cdf952c7 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java @@ -9,6 +9,9 @@ import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; +import com.mapbox.geojson.Feature; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Point; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -19,9 +22,6 @@ import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.sources.GeoJsonOptions; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; -import com.mapbox.services.commons.geojson.Feature; -import com.mapbox.services.commons.geojson.FeatureCollection; -import com.mapbox.services.commons.geojson.Point; import java.util.HashMap; import java.util.List; @@ -78,11 +78,11 @@ final class LocationLayer implements LocationLayerAnimator.OnAnimationsValuesCha LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options) { this.mapboxMap = mapboxMap; this.context = mapView.getContext(); - initializeComponents(); + initializeComponents(options); setRenderMode(RenderMode.NORMAL); } - void initializeComponents() { + void initializeComponents(LocationLayerOptions options) { addLocationSource(); addLayers(); applyStyle(options); @@ -320,7 +320,7 @@ boolean onMapClick(LatLng point) { @Override public void onNewLatLngValue(LatLng latLng) { - Point point = Point.fromCoordinates(new double[] {latLng.getLongitude(), latLng.getLatitude()}); + Point point = Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude()); setLocationPoint(point); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java index 2b9f6ea22..d3d6e7a7e 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java @@ -1,35 +1,61 @@ package com.mapbox.mapboxsdk.plugins.locationlayer; +import android.graphics.PointF; + +import com.mapbox.android.gestures.MoveGestureDetector; +import com.mapbox.android.gestures.RotateGestureDetector; +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode; -public class LocationLayerCamera implements LocationLayerAnimator.OnAnimationsValuesChangeListener { +final class LocationLayerCamera implements LocationLayerAnimator.OnAnimationsValuesChangeListener { @CameraMode.Mode private int cameraMode; - private MapboxMap mapboxMap; + private final MapboxMap mapboxMap; + private final OnCameraTrackingChangedListener internalCameraTrackingChangedListener; + private LocationLayerOptions options; + private boolean adjustFocalPoint; + + private final MoveGestureDetector moveGestureDetector; - public LocationLayerCamera(MapboxMap mapboxMap) { + LocationLayerCamera( + MapboxMap mapboxMap, + OnCameraTrackingChangedListener internalCameraTrackingChangedListener, + LocationLayerOptions options) { this.mapboxMap = mapboxMap; + this.internalCameraTrackingChangedListener = internalCameraTrackingChangedListener; + initializeOptions(options); + + moveGestureDetector = mapboxMap.getGesturesManager().getMoveGestureDetector(); + mapboxMap.addOnMoveListener(onMoveListener); + mapboxMap.addOnRotateListener(onRotateListener); + } + + void initializeOptions(LocationLayerOptions options) { + this.options = options; } - public void setCameraMode(@CameraMode.Mode int cameraMode) { + void setCameraMode(@CameraMode.Mode int cameraMode) { + boolean wasTracking = isLocationTracking(); this.cameraMode = cameraMode; mapboxMap.cancelTransitions(); + adjustGesturesThresholds(); + notifyCameraTrackingChangeListener(wasTracking); } - public int getCameraMode() { + int getCameraMode() { return cameraMode; } private void setBearing(float bearing) { - mapboxMap.setBearing(bearing); + mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(bearing)); } private void setLatLng(LatLng latLng) { - mapboxMap.setLatLng(latLng); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); } @Override @@ -40,6 +66,12 @@ public void onNewLatLngValue(LatLng latLng) { || cameraMode == CameraMode.TRACKING_GPS_NORTH) { setLatLng(latLng); } + + if (adjustFocalPoint) { + PointF focalPoint = mapboxMap.getProjection().toScreenLocation(latLng); + mapboxMap.getUiSettings().setFocalPoint(focalPoint); + adjustFocalPoint = false; + } } @Override @@ -61,9 +93,88 @@ public void onNewCompassBearingValue(float compassBearing) { setBearing(compassBearing); } } -} + private void adjustGesturesThresholds() { + if (isLocationTracking()) { + adjustFocalPoint = true; + moveGestureDetector.setMoveThreshold(options.trackingInitialMoveThreshold()); + } + } + + private boolean isLocationTracking() { + return cameraMode == CameraMode.TRACKING + || cameraMode == CameraMode.TRACKING_COMPASS + || cameraMode == CameraMode.TRACKING_GPS + || cameraMode == CameraMode.TRACKING_GPS_NORTH; + } + + private boolean isBearingTracking() { + return cameraMode == CameraMode.NONE_COMPASS + || cameraMode == CameraMode.TRACKING_COMPASS + || cameraMode == CameraMode.NONE_GPS + || cameraMode == CameraMode.TRACKING_GPS + || cameraMode == CameraMode.TRACKING_GPS_NORTH; + } + + private void notifyCameraTrackingChangeListener(boolean wasTracking) { + internalCameraTrackingChangedListener.onCameraTrackingChanged(cameraMode); + if (wasTracking && !isLocationTracking()) { + mapboxMap.getUiSettings().setFocalPoint(null); + moveGestureDetector.setMoveThreshold(moveGestureDetector.getDefaultMoveThreshold()); + internalCameraTrackingChangedListener.onCameraTrackingDismissed(); + } + } + + private MapboxMap.OnMoveListener onMoveListener = new MapboxMap.OnMoveListener() { + private boolean interrupt; + + @Override + public void onMoveBegin(MoveGestureDetector detector) { + if (detector.getPointersCount() > 1 + && detector.getMoveThreshold() != options.trackingMultiFingerMoveThreshold() + && isLocationTracking()) { + detector.setMoveThreshold(options.trackingMultiFingerMoveThreshold()); + interrupt = true; + } + } -/* + @Override + public void onMove(MoveGestureDetector detector) { + if (interrupt) { + detector.interrupt(); + return; + } - float targetBearing = Utils.shortestRotation(0, (float) bearing);*/ + if (isLocationTracking()) { + setCameraMode(CameraMode.NONE); + } + } + + @Override + public void onMoveEnd(MoveGestureDetector detector) { + if (!interrupt && isLocationTracking()) { + moveGestureDetector.setMoveThreshold(options.trackingInitialMoveThreshold()); + } + interrupt = false; + } + }; + + private MapboxMap.OnRotateListener onRotateListener = new MapboxMap.OnRotateListener() { + @Override + public void onRotateBegin(RotateGestureDetector detector) { + if (isBearingTracking()) { + setCameraMode(CameraMode.NONE); + } + } + + @Override + public void onRotate(RotateGestureDetector detector) { + // no implementation + } + + @Override + public void onRotateEnd(RotateGestureDetector detector) { + // no implementation + } + }; +} \ No newline at end of file diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java index 05dede55a..18b4b7fdb 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java @@ -129,6 +129,15 @@ public static LocationLayerOptions createFromAttributes(@NonNull Context context R.styleable.mapbox_LocationLayer_mapbox_accuracyAlpha, ACCURACY_ALPHA_DEFAULT)); builder.elevation(elevation); + float defaultTrackingInitialMoveThreshold = + context.getResources().getDimension(R.dimen.mapbox_locationLayerTrackingInitialMoveThreshold); + + float defaultTrackingMultiFingerMoveThreshold = + context.getResources().getDimension(R.dimen.mapbox_locationLayerTrackingMultiFingerMoveThreshold); + + builder.trackingInitialMoveThreshold(defaultTrackingInitialMoveThreshold); + builder.trackingMultiFingerMoveThreshold(defaultTrackingMultiFingerMoveThreshold); + typedArray.recycle(); return builder.build(); @@ -372,6 +381,22 @@ private static Builder builder() { */ public abstract double minZoom(); + /** + * Minimum single pointer movement in pixels required to break camera tracking. + * + * @return the minimum movement + * @since 0.5.0 + */ + public abstract float trackingInitialMoveThreshold(); + + /** + * Minimum multi pointer movement in pixels required to break camera tracking (for example during scale gesture). + * + * @return the minimum movement + * @since 0.5.0 + */ + public abstract float trackingMultiFingerMoveThreshold(); + /** * Builder class for constructing a new instance of {@link LocationLayerOptions}. * @@ -580,6 +605,23 @@ public abstract static class Builder { */ public abstract Builder minZoom(double minZoom); + /** + * Sets minimum single pointer movement (map pan) in pixels required to break camera tracking. + * + * @param moveThreshold the minimum movement + * @since 0.5.0 + */ + public abstract Builder trackingInitialMoveThreshold(float moveThreshold); + + /** + * Sets minimum multi pointer movement (map pan) in pixels required to break camera tracking + * (for example during scale gesture). + * + * @param moveThreshold the minimum movement + * @since 0.5.0 + */ + public abstract Builder trackingMultiFingerMoveThreshold(float moveThreshold); + abstract LocationLayerOptions autoBuild(); /** diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index 2f7e75c93..e1a9a94f6 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -74,6 +74,8 @@ public final class LocationLayerPlugin implements LifecycleObserver { = new CopyOnWriteArrayList<>(); private final CopyOnWriteArrayList onLocationLayerLongClickListeners = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList onCameraTrackingChangedListeners + = new CopyOnWriteArrayList<>(); /** * Construct a LocationLayerPlugin @@ -189,7 +191,6 @@ public void setRenderMode(@RenderMode.Mode int renderMode) { locationLayer.setRenderMode(renderMode); } - /** * Provides the current render mode being used to show * the location and/or compass updates on the map. @@ -229,11 +230,13 @@ public void applyStyle(@StyleRes int styleRes) { * @since 0.4.0 */ public void applyStyle(LocationLayerOptions options) { + this.options = options; locationLayer.applyStyle(options); if (!options.enableStaleState()) { staleStateManager.onStop(); } staleStateManager.setDelayTime(options.staleStateTimeout()); + updateMapWithOptions(options); } /** @@ -402,6 +405,26 @@ public void removeOnLocationLongClickListener(@NonNull OnLocationLayerLongClickL onLocationLayerLongClickListeners.remove(listener); } + /** + * Adds a listener that gets invoked when camera tracking state changes. + * + * @param listener Listener that gets invoked when camera tracking state changes. + * @since 0.5.0 + */ + public void addOnCameraTrackingChangedListener(@NonNull OnCameraTrackingChangedListener listener) { + onCameraTrackingChangedListeners.add(listener); + } + + /** + * Removes a listener that gets invoked when camera tracking state changes. + * + * @param listener Listener that gets invoked when camera tracking state changes. + * @since 0.5.0 + */ + public void removeOnCameraTrackingChangedListener(@NonNull OnCameraTrackingChangedListener listener) { + onCameraTrackingChangedListeners.remove(listener); + } + /** * Adds the passed listener that gets invoked when user updates have stopped long enough for the last update * to be considered stale. @@ -476,7 +499,7 @@ private void initialize() { updateMapWithOptions(options); locationLayer = new LocationLayer(mapView, mapboxMap, options); - locationLayerCamera = new LocationLayerCamera(mapboxMap); + locationLayerCamera = new LocationLayerCamera(mapboxMap, cameraTrackingChangedListener, options); locationLayerAnimator = new LocationLayerAnimator(); locationLayerAnimator.addListener(locationLayer); locationLayerAnimator.addListener(locationLayerCamera); @@ -601,7 +624,8 @@ public void onMapChanged(int change) { if (change == MapView.WILL_START_LOADING_MAP) { onStop(); } else if (change == MapView.DID_FINISH_LOADING_STYLE) { - locationLayer.initializeComponents(); + locationLayer.initializeComponents(options); + locationLayerCamera.initializeOptions(options); setRenderMode(locationLayer.getRenderMode()); onStart(); } @@ -634,4 +658,20 @@ public void onLocationChanged(Location location) { updateLocation(location); } }; + + private OnCameraTrackingChangedListener cameraTrackingChangedListener = new OnCameraTrackingChangedListener() { + @Override + public void onCameraTrackingDismissed() { + for (OnCameraTrackingChangedListener listener : onCameraTrackingChangedListeners) { + listener.onCameraTrackingDismissed(); + } + } + + @Override + public void onCameraTrackingChanged(int currentMode) { + for (OnCameraTrackingChangedListener listener : onCameraTrackingChangedListeners) { + listener.onCameraTrackingChanged(currentMode); + } + } + }; } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnCameraTrackingChangedListener.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnCameraTrackingChangedListener.java new file mode 100644 index 000000000..272b3c73f --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnCameraTrackingChangedListener.java @@ -0,0 +1,21 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode; + +/** + * Listener that gets invoked when camera tracking state changes. + */ +public interface OnCameraTrackingChangedListener { + /** + * Invoked whenever camera tracking is broken. + * This callback gets invoked just after {@link #onCameraTrackingChanged(int)}, if needed. + */ + void onCameraTrackingDismissed(); + + /** + * Invoked on every {@link CameraMode} change. + * + * @param currentMode current active {@link CameraMode}. + */ + void onCameraTrackingChanged(@CameraMode.Mode int currentMode); +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/Utils.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/Utils.java index 0d96a61b9..4e627a869 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/Utils.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/Utils.java @@ -1,6 +1,5 @@ package com.mapbox.mapboxsdk.plugins.locationlayer; -import android.animation.TypeEvaluator; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -13,8 +12,6 @@ import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; -import com.mapbox.services.commons.geojson.Point; - public final class Utils { private Utils() { @@ -80,24 +77,6 @@ static Drawable getDrawable(@NonNull Context context, @DrawableRes int drawableR return drawable; } - /** - * Used for animating the user location icon - * - * @since 0.1.0 - */ - static class PointEvaluator implements TypeEvaluator { - // Method is used to interpolate the user icon animation. - @Override - public Point evaluate(float fraction, Point startValue, Point endValue) { - return Point.fromCoordinates(new double[] { - startValue.getCoordinates().getLongitude() + ( - (endValue.getCoordinates().getLongitude() - startValue.getCoordinates().getLongitude()) * fraction), - startValue.getCoordinates().getLatitude() + ( - (endValue.getCoordinates().getLatitude() - startValue.getCoordinates().getLatitude()) * fraction) - }); - } - } - /** * Casts the value to an even integer. */ diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java index 980492ab2..3a6218971 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java @@ -7,6 +7,7 @@ import android.support.annotation.Nullable; import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.plugins.locationlayer.Utils; @@ -80,7 +81,7 @@ public Builder addLatLngAnimator(@NonNull LatLngAnimator latLngAnimator) { latLngAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { - mapboxMap.setLatLng((LatLng) animation.getAnimatedValue()); + mapboxMap.moveCamera(CameraUpdateFactory.newLatLng((LatLng) animation.getAnimatedValue())); } }); @@ -99,7 +100,7 @@ public Builder addZoomAnimator(@NonNull ZoomAnimator zoomAnimator) { zoomAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { - mapboxMap.setZoom((Float) animation.getAnimatedValue()); + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo((Float) animation.getAnimatedValue())); } }); @@ -119,7 +120,7 @@ public Builder addBearingAnimator(@NonNull BearingAnimator bearingAnimator) { bearingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { - mapboxMap.setBearing((Float) animation.getAnimatedValue()); + mapboxMap.moveCamera(CameraUpdateFactory.bearingTo((Float) animation.getAnimatedValue())); } }); @@ -138,7 +139,7 @@ public Builder addTiltAnimator(@NonNull TiltAnimator tiltAnimator) { tiltAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { - mapboxMap.setTilt((Float) animation.getAnimatedValue()); + mapboxMap.moveCamera(CameraUpdateFactory.tiltTo((Float) animation.getAnimatedValue())); } }); @@ -147,7 +148,6 @@ public void onAnimationUpdate(ValueAnimator animation) { } - public MapAnimator build() { return new MapAnimator(animators); } diff --git a/plugin-locationlayer/src/main/res/values/dimens.xml b/plugin-locationlayer/src/main/res/values/dimens.xml new file mode 100644 index 000000000..2957eadbd --- /dev/null +++ b/plugin-locationlayer/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 50dp + 100dp + \ No newline at end of file diff --git a/plugin-locationlayer/src/test/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptionsTest.java b/plugin-locationlayer/src/test/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptionsTest.java index f11aab329..73f8d273b 100644 --- a/plugin-locationlayer/src/test/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptionsTest.java +++ b/plugin-locationlayer/src/test/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptionsTest.java @@ -1,6 +1,7 @@ package com.mapbox.mapboxsdk.plugins.locationlayer; import android.content.Context; +import android.content.res.Resources; import android.content.res.TypedArray; import org.junit.Before; @@ -21,6 +22,8 @@ public class LocationLayerOptionsTest { private Context context; @Mock private TypedArray array; + @Mock + private Resources resources; @Rule public ExpectedException thrown = ExpectedException.none(); @@ -31,6 +34,7 @@ public void setUp() throws Exception { .thenReturn(array); when(array.getResourceId(R.styleable.mapbox_LocationLayer_mapbox_foregroundDrawable, -1)) .thenReturn(R.drawable.mapbox_user_icon); + when(context.getResources()).thenReturn(resources); } @Test