summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorŁukasz Paczos <lukasz.paczos@mapbox.com>2019-01-03 15:59:39 +0100
committerŁukasz Paczos <lukas.paczos@gmail.com>2019-01-29 15:11:01 +0100
commitadd96bebe14017da84b08a5a7f83be6f2fbd7e5c (patch)
treeb9ec563cb60cb57a4267a7aa309784718d4dce9f
parent472e61da39a3e01d8b7a482d8e5c4351c905055b (diff)
downloadqtlocation-mapboxgl-add96bebe14017da84b08a5a7f83be6f2fbd7e5c.tar.gz
[android] optimize location animators memory footprint and add animation rate throttle option
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/AnimatorListenerHolder.java45
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraCompassBearingAnimator.java25
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraGpsBearingAnimator.java24
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraLatLngAnimator.java26
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerAccuracyAnimator.java25
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerCompassBearingAnimator.java25
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerGpsBearingAnimator.java24
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerLatLngAnimator.java26
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinator.java192
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java99
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java28
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java80
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxAnimator.java73
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxCameraAnimatorAdapter.java9
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxFloatAnimator.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxLatLngAnimator.java11
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/OnRenderModeChangedListener.java16
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/TiltAnimator.java28
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/ZoomAnimator.java29
19 files changed, 351 insertions, 442 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/AnimatorListenerHolder.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/AnimatorListenerHolder.java
new file mode 100644
index 0000000000..5dcf30919f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/AnimatorListenerHolder.java
@@ -0,0 +1,45 @@
+package com.mapbox.mapboxsdk.location;
+
+class AnimatorListenerHolder {
+ @MapboxAnimator.Type
+ private final int animatorType;
+ private final MapboxAnimator.AnimationsValueChangeListener listener;
+
+ AnimatorListenerHolder(@MapboxAnimator.Type int animatorType, MapboxAnimator.AnimationsValueChangeListener listener) {
+ this.animatorType = animatorType;
+ this.listener = listener;
+ }
+
+ @MapboxAnimator.Type
+ public int getAnimatorType() {
+ return animatorType;
+ }
+
+ public MapboxAnimator.AnimationsValueChangeListener getListener() {
+ return listener;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ AnimatorListenerHolder that = (AnimatorListenerHolder) o;
+
+ if (animatorType != that.animatorType) {
+ return false;
+ }
+ return listener != null ? listener.equals(that.listener) : that.listener == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = animatorType;
+ result = 31 * result + (listener != null ? listener.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraCompassBearingAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraCompassBearingAnimator.java
deleted file mode 100644
index 4bb20ba5a0..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraCompassBearingAnimator.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.animation.ValueAnimator;
-import android.support.annotation.NonNull;
-
-import java.util.List;
-
-class CameraCompassBearingAnimator extends MapboxFloatAnimator<MapboxAnimator.OnCameraAnimationsValuesChangeListener> {
- CameraCompassBearingAnimator(Float previous, Float target,
- List<OnCameraAnimationsValuesChangeListener> updateListeners) {
- super(previous, target, updateListeners);
- }
-
- @Override
- int provideAnimatorType() {
- return ANIMATOR_CAMERA_COMPASS_BEARING;
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- for (OnCameraAnimationsValuesChangeListener listener : updateListeners) {
- listener.onNewCompassBearingValue((Float) animation.getAnimatedValue());
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraGpsBearingAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraGpsBearingAnimator.java
deleted file mode 100644
index bd8e153d6e..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraGpsBearingAnimator.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.animation.ValueAnimator;
-import android.support.annotation.NonNull;
-
-import java.util.List;
-
-class CameraGpsBearingAnimator extends MapboxFloatAnimator<MapboxAnimator.OnCameraAnimationsValuesChangeListener> {
- CameraGpsBearingAnimator(Float previous, Float target, List<OnCameraAnimationsValuesChangeListener> updateListeners) {
- super(previous, target, updateListeners);
- }
-
- @Override
- int provideAnimatorType() {
- return ANIMATOR_CAMERA_GPS_BEARING;
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- for (OnCameraAnimationsValuesChangeListener listener : updateListeners) {
- listener.onNewGpsBearingValue((Float) animation.getAnimatedValue());
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraLatLngAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraLatLngAnimator.java
deleted file mode 100644
index 8e515b85c8..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/CameraLatLngAnimator.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.animation.ValueAnimator;
-
-import android.support.annotation.NonNull;
-import com.mapbox.mapboxsdk.geometry.LatLng;
-
-import java.util.List;
-
-class CameraLatLngAnimator extends MapboxLatLngAnimator<MapboxAnimator.OnCameraAnimationsValuesChangeListener> {
- CameraLatLngAnimator(LatLng previous, LatLng target, List<OnCameraAnimationsValuesChangeListener> updateListeners) {
- super(previous, target, updateListeners);
- }
-
- @Override
- int provideAnimatorType() {
- return ANIMATOR_CAMERA_LATLNG;
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- for (OnCameraAnimationsValuesChangeListener listener : updateListeners) {
- listener.onNewLatLngValue((LatLng) animation.getAnimatedValue());
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerAccuracyAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerAccuracyAnimator.java
deleted file mode 100644
index 90ed9a0603..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerAccuracyAnimator.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.animation.ValueAnimator;
-import android.support.annotation.NonNull;
-
-import java.util.List;
-
-class LayerAccuracyAnimator extends MapboxFloatAnimator<MapboxAnimator.OnLayerAnimationsValuesChangeListener> {
-
- LayerAccuracyAnimator(Float previous, Float target, List<OnLayerAnimationsValuesChangeListener> updateListeners) {
- super(previous, target, updateListeners);
- }
-
- @Override
- int provideAnimatorType() {
- return ANIMATOR_LAYER_ACCURACY;
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- for (OnLayerAnimationsValuesChangeListener listener : updateListeners) {
- listener.onNewAccuracyRadiusValue((Float) animation.getAnimatedValue());
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerCompassBearingAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerCompassBearingAnimator.java
deleted file mode 100644
index 3b06e0e174..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerCompassBearingAnimator.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.animation.ValueAnimator;
-import android.support.annotation.NonNull;
-
-import java.util.List;
-
-class LayerCompassBearingAnimator extends MapboxFloatAnimator<MapboxAnimator.OnLayerAnimationsValuesChangeListener> {
- LayerCompassBearingAnimator(Float previous,
- Float target, List<OnLayerAnimationsValuesChangeListener> updateListeners) {
- super(previous, target, updateListeners);
- }
-
- @Override
- int provideAnimatorType() {
- return ANIMATOR_LAYER_COMPASS_BEARING;
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- for (OnLayerAnimationsValuesChangeListener listener : updateListeners) {
- listener.onNewCompassBearingValue((Float) animation.getAnimatedValue());
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerGpsBearingAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerGpsBearingAnimator.java
deleted file mode 100644
index 6301f31ee5..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerGpsBearingAnimator.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.animation.ValueAnimator;
-import android.support.annotation.NonNull;
-
-import java.util.List;
-
-class LayerGpsBearingAnimator extends MapboxFloatAnimator<MapboxAnimator.OnLayerAnimationsValuesChangeListener> {
- LayerGpsBearingAnimator(Float previous, Float target, List<OnLayerAnimationsValuesChangeListener> updateListeners) {
- super(previous, target, updateListeners);
- }
-
- @Override
- int provideAnimatorType() {
- return ANIMATOR_LAYER_GPS_BEARING;
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- for (OnLayerAnimationsValuesChangeListener listener : updateListeners) {
- listener.onNewGpsBearingValue((Float) animation.getAnimatedValue());
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerLatLngAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerLatLngAnimator.java
deleted file mode 100644
index 6bfec87430..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LayerLatLngAnimator.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.animation.ValueAnimator;
-
-import android.support.annotation.NonNull;
-import com.mapbox.mapboxsdk.geometry.LatLng;
-
-import java.util.List;
-
-class LayerLatLngAnimator extends MapboxLatLngAnimator<MapboxAnimator.OnLayerAnimationsValuesChangeListener> {
- LayerLatLngAnimator(LatLng previous, LatLng target, List<OnLayerAnimationsValuesChangeListener> updateListeners) {
- super(previous, target, updateListeners);
- }
-
- @Override
- int provideAnimatorType() {
- return ANIMATOR_LAYER_LATLNG;
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- for (OnLayerAnimationsValuesChangeListener listener : updateListeners) {
- listener.onNewLatLngValue((LatLng) animation.getAnimatedValue());
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinator.java
index 4a9705a33b..07af010b6e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinator.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinator.java
@@ -5,7 +5,6 @@ import android.location.Location;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.SparseArray;
import android.view.animation.LinearInterpolator;
@@ -16,6 +15,7 @@ import com.mapbox.mapboxsdk.maps.Projection;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import static com.mapbox.mapboxsdk.location.LocationComponentConstants.ACCURACY_RADIUS_ANIMATION_DURATION;
import static com.mapbox.mapboxsdk.location.LocationComponentConstants.COMPASS_UPDATE_RATE_MS;
@@ -36,9 +36,6 @@ final class LocationAnimatorCoordinator {
final SparseArray<MapboxAnimator> animatorArray = new SparseArray<>();
- final List<MapboxAnimator.OnLayerAnimationsValuesChangeListener> layerListeners = new ArrayList<>();
- final List<MapboxAnimator.OnCameraAnimationsValuesChangeListener> cameraListeners = new ArrayList<>();
-
private final Projection projection;
private Location previousLocation;
private float previousAccuracyRadius = -1;
@@ -48,26 +45,27 @@ final class LocationAnimatorCoordinator {
private final MapboxAnimatorSetProvider animatorSetProvider;
private boolean compassAnimationEnabled;
private boolean accuracyAnimationEnabled;
+ private int maxAnimationFps = Integer.MAX_VALUE;
+
+ private MapboxAnimator.AnimationsValueChangeListener[] listeners;
LocationAnimatorCoordinator(@NonNull Projection projection, @NonNull MapboxAnimatorSetProvider animatorSetProvider) {
this.projection = projection;
this.animatorSetProvider = animatorSetProvider;
}
- void addLayerListener(MapboxAnimator.OnLayerAnimationsValuesChangeListener listener) {
- layerListeners.add(listener);
- }
-
- void removeLayerListener(MapboxAnimator.OnLayerAnimationsValuesChangeListener listener) {
- layerListeners.remove(listener);
- }
-
- void addCameraListener(MapboxAnimator.OnCameraAnimationsValuesChangeListener listener) {
- cameraListeners.add(listener);
- }
+ void updateAnimatorListenerHolders(@NonNull Set<AnimatorListenerHolder> listenerHolders) {
+ int maxIndex = 0;
+ for (AnimatorListenerHolder holder : listenerHolders) {
+ if (holder.getAnimatorType() > maxIndex) {
+ maxIndex = holder.getAnimatorType();
+ }
+ }
- void removeCameraListener(MapboxAnimator.OnCameraAnimationsValuesChangeListener listener) {
- cameraListeners.remove(listener);
+ listeners = new MapboxAnimator.AnimationsValueChangeListener[maxIndex + 1];
+ for (AnimatorListenerHolder holder : listenerHolders) {
+ listeners[holder.getAnimatorType()] = holder.getListener();
+ }
}
void feedNewLocation(@NonNull Location newLocation, @NonNull CameraPosition currentCameraPosition,
@@ -92,7 +90,12 @@ final class LocationAnimatorCoordinator {
boolean snap = immediateAnimation(projection, previousCameraLatLng, targetLatLng)
|| immediateAnimation(projection, previousLayerLatLng, targetLatLng);
- playLocationAnimators(snap ? 0 : getAnimationDuration());
+ playAnimators(
+ snap ? 0 : getAnimationDuration(),
+ ANIMATOR_LAYER_LATLNG,
+ ANIMATOR_LAYER_GPS_BEARING,
+ ANIMATOR_CAMERA_LATLNG,
+ ANIMATOR_CAMERA_GPS_BEARING);
previousLocation = newLocation;
}
@@ -106,7 +109,10 @@ final class LocationAnimatorCoordinator {
float previousCameraBearing = (float) currentCameraPosition.bearing;
updateCompassAnimators(targetCompassBearing, previousLayerBearing, previousCameraBearing);
- playCompassAnimators(compassAnimationEnabled ? COMPASS_UPDATE_RATE_MS : 0);
+ playAnimators(
+ compassAnimationEnabled ? COMPASS_UPDATE_RATE_MS : 0,
+ ANIMATOR_LAYER_COMPASS_BEARING,
+ ANIMATOR_CAMERA_COMPASS_BEARING);
previousCompassBearing = targetCompassBearing;
}
@@ -118,7 +124,9 @@ final class LocationAnimatorCoordinator {
float previousAccuracyRadius = getPreviousAccuracyRadius();
updateAccuracyAnimators(targetAccuracyRadius, previousAccuracyRadius);
- playAccuracyAnimator(noAnimation || !accuracyAnimationEnabled ? 0 : ACCURACY_RADIUS_ANIMATION_DURATION);
+ playAnimators(
+ noAnimation || !accuracyAnimationEnabled ? 0 : ACCURACY_RADIUS_ANIMATION_DURATION,
+ ANIMATOR_LAYER_ACCURACY);
this.previousAccuracyRadius = targetAccuracyRadius;
}
@@ -126,13 +134,13 @@ final class LocationAnimatorCoordinator {
void feedNewZoomLevel(double targetZoomLevel, @NonNull CameraPosition currentCameraPosition, long animationDuration,
@Nullable MapboxMap.CancelableCallback callback) {
updateZoomAnimator((float) targetZoomLevel, (float) currentCameraPosition.zoom, callback);
- playZoomAnimator(animationDuration);
+ playAnimators(animationDuration, ANIMATOR_ZOOM);
}
void feedNewTilt(double targetTilt, @NonNull CameraPosition currentCameraPosition, long animationDuration,
@Nullable MapboxMap.CancelableCallback callback) {
updateTiltAnimator((float) targetTilt, (float) currentCameraPosition.tilt, callback);
- playTiltAnimator(animationDuration);
+ playAnimators(animationDuration, ANIMATOR_TILT);
}
private LatLng getPreviousLayerLatLng() {
@@ -147,7 +155,7 @@ final class LocationAnimatorCoordinator {
}
private float getPreviousLayerGpsBearing() {
- LayerGpsBearingAnimator animator = (LayerGpsBearingAnimator) animatorArray.get(ANIMATOR_LAYER_GPS_BEARING);
+ MapboxFloatAnimator animator = (MapboxFloatAnimator) animatorArray.get(ANIMATOR_LAYER_GPS_BEARING);
float previousBearing;
if (animator != null) {
previousBearing = (float) animator.getAnimatedValue();
@@ -158,8 +166,7 @@ final class LocationAnimatorCoordinator {
}
private float getPreviousLayerCompassBearing() {
- LayerCompassBearingAnimator animator =
- (LayerCompassBearingAnimator) animatorArray.get(ANIMATOR_LAYER_COMPASS_BEARING);
+ MapboxFloatAnimator animator = (MapboxFloatAnimator) animatorArray.get(ANIMATOR_LAYER_COMPASS_BEARING);
float previousBearing;
if (animator != null) {
@@ -171,7 +178,7 @@ final class LocationAnimatorCoordinator {
}
private float getPreviousAccuracyRadius() {
- LayerAccuracyAnimator animator = (LayerAccuracyAnimator) animatorArray.get(ANIMATOR_LAYER_ACCURACY);
+ MapboxAnimator animator = animatorArray.get(ANIMATOR_LAYER_ACCURACY);
float previousRadius;
if (animator != null) {
previousRadius = (float) animator.getAnimatedValue();
@@ -183,49 +190,66 @@ final class LocationAnimatorCoordinator {
private void updateLayerAnimators(LatLng previousLatLng, LatLng targetLatLng,
float previousBearing, float targetBearing) {
- createNewAnimator(ANIMATOR_LAYER_LATLNG, new LayerLatLngAnimator(previousLatLng, targetLatLng, layerListeners));
+ createNewLatLngAnimator(ANIMATOR_LAYER_LATLNG, previousLatLng, targetLatLng);
float normalizedLayerBearing = Utils.shortestRotation(targetBearing, previousBearing);
- createNewAnimator(ANIMATOR_LAYER_GPS_BEARING,
- new LayerGpsBearingAnimator(previousBearing, normalizedLayerBearing, layerListeners));
+ createNewFloatAnimator(ANIMATOR_LAYER_GPS_BEARING, previousBearing, normalizedLayerBearing);
}
private void updateCameraAnimators(LatLng previousCameraLatLng, float previousCameraBearing,
LatLng targetLatLng, float targetBearing) {
- createNewAnimator(ANIMATOR_CAMERA_LATLNG,
- new CameraLatLngAnimator(previousCameraLatLng, targetLatLng, cameraListeners));
+ createNewLatLngAnimator(ANIMATOR_CAMERA_LATLNG, previousCameraLatLng, targetLatLng);
float normalizedCameraBearing = Utils.shortestRotation(targetBearing, previousCameraBearing);
- createNewAnimator(ANIMATOR_CAMERA_GPS_BEARING,
- new CameraGpsBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners));
+ createNewFloatAnimator(ANIMATOR_CAMERA_GPS_BEARING, previousCameraBearing, normalizedCameraBearing);
}
private void updateCompassAnimators(float targetCompassBearing, float previousLayerBearing,
float previousCameraBearing) {
float normalizedLayerBearing = Utils.shortestRotation(targetCompassBearing, previousLayerBearing);
- createNewAnimator(ANIMATOR_LAYER_COMPASS_BEARING,
- new LayerCompassBearingAnimator(previousLayerBearing, normalizedLayerBearing, layerListeners));
+ createNewFloatAnimator(ANIMATOR_LAYER_COMPASS_BEARING, previousLayerBearing, normalizedLayerBearing);
float normalizedCameraBearing = Utils.shortestRotation(targetCompassBearing, previousCameraBearing);
- createNewAnimator(ANIMATOR_CAMERA_COMPASS_BEARING,
- new CameraCompassBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners));
+ createNewFloatAnimator(ANIMATOR_CAMERA_COMPASS_BEARING, previousCameraBearing, normalizedCameraBearing);
}
private void updateAccuracyAnimators(float targetAccuracyRadius, float previousAccuracyRadius) {
- createNewAnimator(ANIMATOR_LAYER_ACCURACY,
- new LayerAccuracyAnimator(previousAccuracyRadius, targetAccuracyRadius, layerListeners));
+ createNewFloatAnimator(ANIMATOR_LAYER_ACCURACY, previousAccuracyRadius, targetAccuracyRadius);
}
private void updateZoomAnimator(float targetZoomLevel, float previousZoomLevel,
@Nullable MapboxMap.CancelableCallback cancelableCallback) {
- createNewAnimator(ANIMATOR_ZOOM,
- new ZoomAnimator(previousZoomLevel, targetZoomLevel, cameraListeners, cancelableCallback));
+ createNewCameraAdapterAnimator(ANIMATOR_ZOOM, previousZoomLevel, targetZoomLevel, cancelableCallback);
}
private void updateTiltAnimator(float targetTilt, float previousTiltLevel,
@Nullable MapboxMap.CancelableCallback cancelableCallback) {
- createNewAnimator(ANIMATOR_TILT,
- new TiltAnimator(previousTiltLevel, targetTilt, cameraListeners, cancelableCallback));
+ createNewCameraAdapterAnimator(ANIMATOR_TILT, previousTiltLevel, targetTilt, cancelableCallback);
+ }
+
+ private void createNewLatLngAnimator(@MapboxAnimator.Type int animatorType, LatLng previous, LatLng target) {
+ cancelAnimator(animatorType);
+ MapboxAnimator.AnimationsValueChangeListener listener = listeners[animatorType];
+ if (listener != null) {
+ animatorArray.put(animatorType, new MapboxLatLngAnimator(previous, target, listener, maxAnimationFps));
+ }
+ }
+
+ private void createNewFloatAnimator(@MapboxAnimator.Type int animatorType, float previous, float target) {
+ cancelAnimator(animatorType);
+ MapboxAnimator.AnimationsValueChangeListener listener = listeners[animatorType];
+ if (listener != null) {
+ animatorArray.put(animatorType, new MapboxFloatAnimator(previous, target, listener, maxAnimationFps));
+ }
+ }
+
+ private void createNewCameraAdapterAnimator(@MapboxAnimator.Type int animatorType, float previous, float target,
+ @Nullable MapboxMap.CancelableCallback cancelableCallback) {
+ cancelAnimator(animatorType);
+ MapboxAnimator.AnimationsValueChangeListener listener = listeners[animatorType];
+ if (listener != null) {
+ animatorArray.put(animatorType, new MapboxCameraAnimatorAdapter(previous, target, listener, cancelableCallback));
+ }
}
private long getAnimationDuration() {
@@ -252,51 +276,24 @@ final class LocationAnimatorCoordinator {
return targetCameraBearing;
}
- private void playLocationAnimators(long duration) {
- List<Animator> locationAnimators = new ArrayList<>();
- locationAnimators.add(animatorArray.get(ANIMATOR_LAYER_LATLNG));
- locationAnimators.add(animatorArray.get(ANIMATOR_LAYER_GPS_BEARING));
- locationAnimators.add(animatorArray.get(ANIMATOR_CAMERA_LATLNG));
- locationAnimators.add(animatorArray.get(ANIMATOR_CAMERA_GPS_BEARING));
- animatorSetProvider.startAnimation(locationAnimators, new LinearInterpolator(), duration);
- }
-
- private void playCompassAnimators(long duration) {
- List<Animator> compassAnimators = new ArrayList<>();
- compassAnimators.add(animatorArray.get(ANIMATOR_LAYER_COMPASS_BEARING));
- compassAnimators.add(animatorArray.get(ANIMATOR_CAMERA_COMPASS_BEARING));
- animatorSetProvider.startAnimation(compassAnimators, new LinearInterpolator(), duration);
- }
-
- private void playAccuracyAnimator(long duration) {
- List<Animator> accuracyAnimators = new ArrayList<>();
- accuracyAnimators.add(animatorArray.get(ANIMATOR_LAYER_ACCURACY));
- animatorSetProvider.startAnimation(accuracyAnimators, new LinearInterpolator(), duration);
- }
-
- private void playZoomAnimator(long duration) {
- MapboxAnimator animator = animatorArray.get(ANIMATOR_ZOOM);
- animator.setDuration(duration);
- animator.start();
- }
-
- private void playTiltAnimator(long duration) {
- MapboxAnimator animator = animatorArray.get(ANIMATOR_TILT);
- animator.setDuration(duration);
- animator.start();
- }
-
- private void playCameraLocationAnimators(long duration) {
- List<Animator> locationAnimators = new ArrayList<>();
- locationAnimators.add(animatorArray.get(ANIMATOR_CAMERA_LATLNG));
- locationAnimators.add(animatorArray.get(ANIMATOR_CAMERA_GPS_BEARING));
- animatorSetProvider.startAnimation(locationAnimators, new FastOutSlowInInterpolator(), duration);
+ private void playAnimators(long duration, @MapboxAnimator.Type int... animatorTypes) {
+ List<Animator> animators = new ArrayList<>();
+ for (@MapboxAnimator.Type int animatorType : animatorTypes) {
+ Animator animator = animatorArray.get(animatorType);
+ if (animator != null) {
+ animators.add(animator);
+ }
+ }
+ animatorSetProvider.startAnimation(animators, new LinearInterpolator(), duration);
}
void resetAllCameraAnimations(@NonNull CameraPosition currentCameraPosition, boolean isGpsNorth) {
resetCameraCompassAnimation(currentCameraPosition);
boolean snap = resetCameraLocationAnimations(currentCameraPosition, isGpsNorth);
- playCameraLocationAnimators(snap ? 0 : TRANSITION_ANIMATION_DURATION_MS);
+ playAnimators(
+ snap ? 0 : TRANSITION_ANIMATION_DURATION_MS,
+ ANIMATOR_CAMERA_LATLNG,
+ ANIMATOR_CAMERA_GPS_BEARING);
}
private boolean resetCameraLocationAnimations(@NonNull CameraPosition currentCameraPosition, boolean isGpsNorth) {
@@ -305,21 +302,20 @@ final class LocationAnimatorCoordinator {
}
private boolean resetCameraLatLngAnimation(@NonNull CameraPosition currentCameraPosition) {
- CameraLatLngAnimator animator = (CameraLatLngAnimator) animatorArray.get(ANIMATOR_CAMERA_LATLNG);
+ MapboxLatLngAnimator animator = (MapboxLatLngAnimator) animatorArray.get(ANIMATOR_CAMERA_LATLNG);
if (animator == null) {
return false;
}
LatLng currentTarget = animator.getTarget();
LatLng previousCameraTarget = currentCameraPosition.target;
- createNewAnimator(ANIMATOR_CAMERA_LATLNG,
- new CameraLatLngAnimator(previousCameraTarget, currentTarget, cameraListeners));
+ createNewLatLngAnimator(ANIMATOR_CAMERA_LATLNG, previousCameraTarget, currentTarget);
return immediateAnimation(projection, previousCameraTarget, currentTarget);
}
private void resetCameraGpsBearingAnimation(@NonNull CameraPosition currentCameraPosition, boolean isGpsNorth) {
- CameraGpsBearingAnimator animator = (CameraGpsBearingAnimator) animatorArray.get(ANIMATOR_CAMERA_GPS_BEARING);
+ MapboxFloatAnimator animator = (MapboxFloatAnimator) animatorArray.get(ANIMATOR_CAMERA_GPS_BEARING);
if (animator == null) {
return;
}
@@ -328,13 +324,12 @@ final class LocationAnimatorCoordinator {
currentTargetBearing = checkGpsNorth(isGpsNorth, currentTargetBearing);
float previousCameraBearing = (float) currentCameraPosition.bearing;
float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing);
- createNewAnimator(ANIMATOR_CAMERA_GPS_BEARING,
- new CameraGpsBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners));
+ createNewFloatAnimator(ANIMATOR_CAMERA_GPS_BEARING, previousCameraBearing, normalizedCameraBearing);
}
private void resetCameraCompassAnimation(@NonNull CameraPosition currentCameraPosition) {
- CameraCompassBearingAnimator animator =
- (CameraCompassBearingAnimator) animatorArray.get(ANIMATOR_CAMERA_COMPASS_BEARING);
+ MapboxFloatAnimator animator =
+ (MapboxFloatAnimator) animatorArray.get(ANIMATOR_CAMERA_COMPASS_BEARING);
if (animator == null) {
return;
}
@@ -342,13 +337,7 @@ final class LocationAnimatorCoordinator {
float currentTargetBearing = animator.getTarget();
float previousCameraBearing = (float) currentCameraPosition.bearing;
float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing);
- createNewAnimator(ANIMATOR_CAMERA_COMPASS_BEARING,
- new CameraCompassBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners));
- }
-
- private void createNewAnimator(@MapboxAnimator.Type int animatorType, MapboxAnimator animator) {
- cancelAnimator(animatorType);
- animatorArray.put(animatorType, animator);
+ createNewFloatAnimator(ANIMATOR_CAMERA_COMPASS_BEARING, previousCameraBearing, normalizedCameraBearing);
}
void cancelZoomAnimation() {
@@ -387,4 +376,11 @@ final class LocationAnimatorCoordinator {
void setAccuracyAnimationEnabled(boolean accuracyAnimationEnabled) {
this.accuracyAnimationEnabled = accuracyAnimationEnabled;
}
+
+ void setMaxAnimationFps(int maxAnimationFps) {
+ if (maxAnimationFps <= 0) {
+ return;
+ }
+ this.maxAnimationFps = maxAnimationFps;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java
index 5e972c51d6..4e56c6e9c0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java
@@ -18,7 +18,10 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.mapboxsdk.maps.MapboxMap;
-final class LocationCameraController implements MapboxAnimator.OnCameraAnimationsValuesChangeListener {
+import java.util.HashSet;
+import java.util.Set;
+
+final class LocationCameraController {
@CameraMode.Mode
private int cameraMode;
@@ -196,44 +199,73 @@ final class LocationCameraController implements MapboxAnimator.OnCameraAnimation
onCameraMoveInvalidateListener.onInvalidateCameraMove();
}
- @Override
- public void onNewLatLngValue(@NonNull LatLng latLng) {
- if (cameraMode == CameraMode.TRACKING
- || cameraMode == CameraMode.TRACKING_COMPASS
- || cameraMode == CameraMode.TRACKING_GPS
- || cameraMode == CameraMode.TRACKING_GPS_NORTH) {
- setLatLng(latLng);
- }
- }
+ private final MapboxAnimator.AnimationsValueChangeListener<LatLng> latLngValueListener =
+ new MapboxAnimator.AnimationsValueChangeListener<LatLng>() {
+ @Override
+ public void onNewAnimationValue(LatLng value) {
+ setLatLng(value);
+ }
+ };
- @Override
- public void onNewGpsBearingValue(float gpsBearing) {
- boolean trackingNorth = cameraMode == CameraMode.TRACKING_GPS_NORTH
- && mapboxMap.getCameraPosition().bearing != 0;
+ private final MapboxAnimator.AnimationsValueChangeListener<Float> gpsBearingValueListener =
+ new MapboxAnimator.AnimationsValueChangeListener<Float>() {
+ @Override
+ public void onNewAnimationValue(Float value) {
+ boolean trackingNorth = cameraMode == CameraMode.TRACKING_GPS_NORTH
+ && mapboxMap.getCameraPosition().bearing == 0;
- if (cameraMode == CameraMode.TRACKING_GPS
- || cameraMode == CameraMode.NONE_GPS
- || trackingNorth) {
- setBearing(gpsBearing);
+ if (!trackingNorth) {
+ setBearing(value);
+ }
+ }
+ };
+
+ private final MapboxAnimator.AnimationsValueChangeListener<Float> compassBearingValueListener =
+ new MapboxAnimator.AnimationsValueChangeListener<Float>() {
+ @Override
+ public void onNewAnimationValue(Float value) {
+ if (cameraMode == CameraMode.TRACKING_COMPASS
+ || cameraMode == CameraMode.NONE_COMPASS) {
+ setBearing(value);
+ }
+ }
+ };
+
+ private final MapboxAnimator.AnimationsValueChangeListener<Float> zoomValueListener =
+ new MapboxAnimator.AnimationsValueChangeListener<Float>() {
+ @Override
+ public void onNewAnimationValue(Float value) {
+ setZoom(value);
+ }
+ };
+
+ private final MapboxAnimator.AnimationsValueChangeListener<Float> tiltValueListener =
+ new MapboxAnimator.AnimationsValueChangeListener<Float>() {
+ @Override
+ public void onNewAnimationValue(Float value) {
+ setTilt(value);
+ }
+ };
+
+ Set<AnimatorListenerHolder> getAnimationListeners() {
+ Set<AnimatorListenerHolder> holders = new HashSet<>();
+ if (isLocationTracking()) {
+ holders.add(new AnimatorListenerHolder(MapboxAnimator.ANIMATOR_CAMERA_LATLNG, latLngValueListener));
}
- }
- @Override
- public void onNewCompassBearingValue(float compassBearing) {
- if (cameraMode == CameraMode.TRACKING_COMPASS
- || cameraMode == CameraMode.NONE_COMPASS) {
- setBearing(compassBearing);
+ if (isLocationBearingTracking()) {
+ holders.add(new AnimatorListenerHolder(MapboxAnimator.ANIMATOR_CAMERA_GPS_BEARING, gpsBearingValueListener));
}
- }
- @Override
- public void onNewZoomValue(float zoom) {
- setZoom(zoom);
- }
+ if (isConsumingCompass()) {
+ holders.add(new AnimatorListenerHolder(
+ MapboxAnimator.ANIMATOR_CAMERA_COMPASS_BEARING,
+ compassBearingValueListener));
+ }
- @Override
- public void onNewTiltValue(float tilt) {
- setTilt(tilt);
+ holders.add(new AnimatorListenerHolder(MapboxAnimator.ANIMATOR_ZOOM, zoomValueListener));
+ holders.add(new AnimatorListenerHolder(MapboxAnimator.ANIMATOR_TILT, tiltValueListener));
+ return holders;
}
boolean isTransitioning() {
@@ -273,7 +305,8 @@ final class LocationCameraController implements MapboxAnimator.OnCameraAnimation
private boolean isLocationBearingTracking() {
return cameraMode == CameraMode.TRACKING_GPS
- || cameraMode == CameraMode.TRACKING_GPS_NORTH;
+ || cameraMode == CameraMode.TRACKING_GPS_NORTH
+ || cameraMode == CameraMode.NONE_GPS;
}
private void notifyCameraTrackingChangeListener(boolean wasTracking) {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
index 92b4288c3b..e8e1f875b0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java
@@ -32,6 +32,8 @@ import com.mapbox.mapboxsdk.maps.MapboxMap.OnMapClickListener;
import com.mapbox.mapboxsdk.maps.Style;
import java.lang.ref.WeakReference;
+import java.util.HashSet;
+import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
@@ -698,6 +700,10 @@ public final class LocationComponent {
updateLocation(location, false);
}
+ public void setMaxAnimationFps(int maxAnimationFps) {
+ locationAnimatorCoordinator.setMaxAnimationFps(maxAnimationFps);
+ }
+
/**
* Set the location engine to update the current user location.
* <p>
@@ -989,7 +995,7 @@ public final class LocationComponent {
LayerFeatureProvider featureProvider = new LayerFeatureProvider();
LayerBitmapProvider bitmapProvider = new LayerBitmapProvider(context);
locationLayerController = new LocationLayerController(mapboxMap, style, sourceProvider, featureProvider,
- bitmapProvider, options);
+ bitmapProvider, options, renderModeChangedListener);
locationCameraController = new LocationCameraController(
context, mapboxMap, cameraTrackingChangedListener, options, onCameraMoveInvalidateListener);
@@ -997,8 +1003,6 @@ public final class LocationComponent {
mapboxMap.getProjection(),
MapboxAnimatorSetProvider.getInstance()
);
- locationAnimatorCoordinator.addLayerListener(locationLayerController);
- locationAnimatorCoordinator.addCameraListener(locationCameraController);
locationAnimatorCoordinator.setTrackingAnimationDurationMultiplier(options
.trackingAnimationDurationMultiplier());
@@ -1164,6 +1168,13 @@ public final class LocationComponent {
locationAnimatorCoordinator.feedNewAccuracyRadius(Utils.calculateZoomLevelRadius(mapboxMap, location), noAnimation);
}
+ private void updateAnimatorListenerHolders() {
+ Set<AnimatorListenerHolder> animationsValueChangeListeners = new HashSet<>();
+ animationsValueChangeListeners.addAll(locationLayerController.getAnimationListeners());
+ animationsValueChangeListeners.addAll(locationCameraController.getAnimationListeners());
+ locationAnimatorCoordinator.updateAnimatorListenerHolders(animationsValueChangeListeners);
+ }
+
@NonNull
private OnCameraMoveListener onCameraMoveListener = new OnCameraMoveListener() {
@Override
@@ -1298,12 +1309,23 @@ public final class LocationComponent {
public void onCameraTrackingChanged(int currentMode) {
locationAnimatorCoordinator.cancelZoomAnimation();
locationAnimatorCoordinator.cancelTiltAnimation();
+ updateAnimatorListenerHolders();
+ locationAnimatorCoordinator.resetAllCameraAnimations(mapboxMap.getCameraPosition(),
+ locationCameraController.getCameraMode() == CameraMode.TRACKING_GPS_NORTH);
for (OnCameraTrackingChangedListener listener : onCameraTrackingChangedListeners) {
listener.onCameraTrackingChanged(currentMode);
}
}
};
+ @NonNull
+ private OnRenderModeChangedListener renderModeChangedListener = new OnRenderModeChangedListener() {
+ @Override
+ public void onRenderModeChanged(int currentMode) {
+ updateAnimatorListenerHolders();
+ }
+ };
+
static class InternalLocationEngineProvider {
LocationEngine getBestLocationEngine(@NonNull Context context, boolean background) {
return LocationEngineProvider.getBestLocationEngine(context, background);
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java
index f5d92ae810..c726caacfb 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationLayerController.java
@@ -19,7 +19,9 @@ import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import static com.mapbox.mapboxsdk.location.LocationComponentConstants.ACCURACY_LAYER;
import static com.mapbox.mapboxsdk.location.LocationComponentConstants.BACKGROUND_ICON;
@@ -56,7 +58,7 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
import static com.mapbox.mapboxsdk.utils.ColorUtils.colorToRgbaString;
-final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsValuesChangeListener {
+final class LocationLayerController {
@RenderMode.Mode
private int renderMode;
@@ -66,6 +68,7 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV
private final LayerSourceProvider layerSourceProvider;
private final LayerBitmapProvider bitmapProvider;
private LocationComponentOptions options;
+ private final OnRenderModeChangedListener internalRenderModeChangedListener;
private final List<String> layerMap = new ArrayList<>();
private Feature locationFeature;
@@ -78,14 +81,15 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV
LocationLayerController(MapboxMap mapboxMap, Style style, LayerSourceProvider layerSourceProvider,
LayerFeatureProvider featureProvider, LayerBitmapProvider bitmapProvider,
- @NonNull LocationComponentOptions options) {
+ @NonNull LocationComponentOptions options,
+ @NonNull OnRenderModeChangedListener internalRenderModeChangedListener) {
this.mapboxMap = mapboxMap;
this.style = style;
this.layerSourceProvider = layerSourceProvider;
this.bitmapProvider = bitmapProvider;
this.locationFeature = featureProvider.generateLocationFeature(locationFeature, options);
+ this.internalRenderModeChangedListener = internalRenderModeChangedListener;
initializeComponents(style, options);
- setRenderMode(RenderMode.NORMAL);
}
void initializeComponents(Style style, LocationComponentOptions options) {
@@ -127,6 +131,7 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV
}
void setRenderMode(@RenderMode.Mode int renderMode) {
+ int previousMode = this.renderMode;
this.renderMode = renderMode;
if (!isHidden) {
@@ -162,6 +167,10 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV
determineIconsSource(options);
}
+
+ if (previousMode != renderMode) {
+ internalRenderModeChangedListener.onRenderModeChanged(renderMode);
+ }
}
int getRenderMode() {
@@ -259,10 +268,8 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV
}
private void updateAccuracyRadius(float accuracy) {
- if (renderMode == RenderMode.COMPASS || renderMode == RenderMode.NORMAL) {
- locationFeature.addNumberProperty(PROPERTY_ACCURACY_RADIUS, accuracy);
- refreshSource();
- }
+ locationFeature.addNumberProperty(PROPERTY_ACCURACY_RADIUS, accuracy);
+ refreshSource();
}
//
@@ -400,28 +407,53 @@ final class LocationLayerController implements MapboxAnimator.OnLayerAnimationsV
return !features.isEmpty();
}
- @Override
- public void onNewLatLngValue(LatLng latLng) {
- Point point = Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude());
- setLocationPoint(point);
- }
+ private final MapboxAnimator.AnimationsValueChangeListener<LatLng> latLngValueListener =
+ new MapboxAnimator.AnimationsValueChangeListener<LatLng>() {
+ @Override
+ public void onNewAnimationValue(LatLng value) {
+ Point point = Point.fromLngLat(value.getLongitude(), value.getLatitude());
+ setLocationPoint(point);
+ }
+ };
+
+ private final MapboxAnimator.AnimationsValueChangeListener<Float> gpsBearingValueListener =
+ new MapboxAnimator.AnimationsValueChangeListener<Float>() {
+ @Override
+ public void onNewAnimationValue(Float value) {
+ setBearingProperty(PROPERTY_GPS_BEARING, value);
+ }
+ };
+
+ private final MapboxAnimator.AnimationsValueChangeListener<Float> compassBearingValueListener =
+ new MapboxAnimator.AnimationsValueChangeListener<Float>() {
+ @Override
+ public void onNewAnimationValue(Float value) {
+ setBearingProperty(PROPERTY_COMPASS_BEARING, value);
+ }
+ };
+
+ private final MapboxAnimator.AnimationsValueChangeListener<Float> accuracyValueListener =
+ new MapboxAnimator.AnimationsValueChangeListener<Float>() {
+ @Override
+ public void onNewAnimationValue(Float value) {
+ updateAccuracyRadius(value);
+ }
+ };
+
+ Set<AnimatorListenerHolder> getAnimationListeners() {
+ Set<AnimatorListenerHolder> holders = new HashSet<>();
+ holders.add(new AnimatorListenerHolder(MapboxAnimator.ANIMATOR_LAYER_LATLNG, latLngValueListener));
- @Override
- public void onNewGpsBearingValue(float gpsBearing) {
if (renderMode == RenderMode.GPS) {
- setBearingProperty(PROPERTY_GPS_BEARING, gpsBearing);
+ holders.add(new AnimatorListenerHolder(MapboxAnimator.ANIMATOR_LAYER_GPS_BEARING, gpsBearingValueListener));
+ } else if (renderMode == RenderMode.COMPASS) {
+ holders.add(new AnimatorListenerHolder(MapboxAnimator.ANIMATOR_LAYER_COMPASS_BEARING, compassBearingValueListener));
}
- }
- @Override
- public void onNewCompassBearingValue(float compassBearing) {
- if (renderMode == RenderMode.COMPASS) {
- setBearingProperty(PROPERTY_COMPASS_BEARING, compassBearing);
+ if (renderMode == RenderMode.COMPASS || renderMode == RenderMode.NORMAL) {
+ holders.add(new AnimatorListenerHolder(MapboxAnimator.ANIMATOR_LAYER_ACCURACY, accuracyValueListener));
}
- }
- @Override
- public void onNewAccuracyRadiusValue(float accuracyRadiusValue) {
- updateAccuracyRadius(accuracyRadiusValue);
+ return holders;
}
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxAnimator.java
index a72bf08a86..ab8b782249 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxAnimator.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxAnimator.java
@@ -1,22 +1,21 @@
package com.mapbox.mapboxsdk.location;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.support.annotation.IntDef;
-
-import com.mapbox.mapboxsdk.geometry.LatLng;
+import android.support.annotation.NonNull;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.List;
/**
* Abstract class for all of the location component animators.
*
* @param <K> Data type that will be animated.
- * @param <L> Listener of animation updates.
*/
-abstract class MapboxAnimator<K, L> extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener {
+abstract class MapboxAnimator<K> extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener {
@Retention(RetentionPolicy.SOURCE)
@IntDef( {
ANIMATOR_LAYER_LATLNG,
@@ -42,51 +41,55 @@ abstract class MapboxAnimator<K, L> extends ValueAnimator implements ValueAnimat
static final int ANIMATOR_ZOOM = 7;
static final int ANIMATOR_TILT = 8;
- private final int animatorType = provideAnimatorType();
- final List<L> updateListeners;
+ private final AnimationsValueChangeListener<K> updateListener;
private final K target;
+ private K animatedValue;
+
+ private double minUpdateInterval;
+ private long timeElapsed;
- MapboxAnimator(K previous, K target, List<L> updateListeners) {
+ MapboxAnimator(@NonNull K previous, @NonNull K target, @NonNull AnimationsValueChangeListener<K> updateListener,
+ int maxAnimationFps) {
+ minUpdateInterval = 1E9 / maxAnimationFps;
setObjectValues(previous, target);
setEvaluator(provideEvaluator());
- this.updateListeners = updateListeners;
+ this.updateListener = updateListener;
this.target = target;
addUpdateListener(this);
+ addListener(new AnimatorListener());
}
- K getTarget() {
- return target;
- }
-
- @Type
- int getAnimatorType() {
- return animatorType;
- }
-
- @Type
- abstract int provideAnimatorType();
-
- abstract TypeEvaluator provideEvaluator();
-
- interface OnLayerAnimationsValuesChangeListener {
- void onNewLatLngValue(LatLng latLng);
-
- void onNewGpsBearingValue(float gpsBearing);
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ animatedValue = (K) animation.getAnimatedValue();
- void onNewCompassBearingValue(float compassBearing);
+ long currentTime = System.nanoTime();
+ if ((currentTime - timeElapsed) < minUpdateInterval) {
+ return;
+ }
- void onNewAccuracyRadiusValue(float accuracyRadiusValue);
+ postUpdates();
+ timeElapsed = currentTime;
}
- interface OnCameraAnimationsValuesChangeListener {
- void onNewLatLngValue(LatLng latLng);
+ private class AnimatorListener extends AnimatorListenerAdapter {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ postUpdates();
+ }
+ }
- void onNewGpsBearingValue(float gpsBearing);
+ private void postUpdates() {
+ updateListener.onNewAnimationValue(animatedValue);
+ }
- void onNewCompassBearingValue(float compassBearing);
+ K getTarget() {
+ return target;
+ }
- void onNewZoomValue(float zoom);
+ abstract TypeEvaluator provideEvaluator();
- void onNewTiltValue(float tilt);
+ interface AnimationsValueChangeListener<K> {
+ void onNewAnimationValue(K value);
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxCameraAnimatorAdapter.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxCameraAnimatorAdapter.java
index b4f9051af8..24bb82a2d7 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxCameraAnimatorAdapter.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxCameraAnimatorAdapter.java
@@ -6,17 +6,14 @@ import android.support.annotation.Nullable;
import com.mapbox.mapboxsdk.maps.MapboxMap;
-import java.util.List;
-
-abstract class MapboxCameraAnimatorAdapter extends
- MapboxFloatAnimator<MapboxAnimator.OnCameraAnimationsValuesChangeListener> {
+class MapboxCameraAnimatorAdapter extends MapboxFloatAnimator {
@Nullable
private final MapboxMap.CancelableCallback cancelableCallback;
MapboxCameraAnimatorAdapter(Float previous, Float target,
- List<OnCameraAnimationsValuesChangeListener> updateListeners,
+ AnimationsValueChangeListener updateListener,
@Nullable MapboxMap.CancelableCallback cancelableCallback) {
- super(previous, target, updateListeners);
+ super(previous, target, updateListener, Integer.MAX_VALUE);
this.cancelableCallback = cancelableCallback;
addListener(new MapboxAnimatorListener());
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxFloatAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxFloatAnimator.java
index d12e80a69d..d7d518bc8f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxFloatAnimator.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxFloatAnimator.java
@@ -4,11 +4,9 @@ import android.animation.FloatEvaluator;
import android.animation.TypeEvaluator;
import android.support.annotation.NonNull;
-import java.util.List;
-
-abstract class MapboxFloatAnimator<L> extends MapboxAnimator<Float, L> {
- MapboxFloatAnimator(Float previous, Float target, List<L> updateListeners) {
- super(previous, target, updateListeners);
+class MapboxFloatAnimator extends MapboxAnimator<Float> {
+ MapboxFloatAnimator(Float previous, Float target, AnimationsValueChangeListener updateListener, int maxAnimationFps) {
+ super(previous, target, updateListener, maxAnimationFps);
}
@NonNull
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxLatLngAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxLatLngAnimator.java
index f2c5f9a239..5070691143 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxLatLngAnimator.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/MapboxLatLngAnimator.java
@@ -1,16 +1,15 @@
package com.mapbox.mapboxsdk.location;
import android.animation.TypeEvaluator;
-
import android.support.annotation.NonNull;
-import com.mapbox.mapboxsdk.geometry.LatLng;
-import java.util.List;
+import com.mapbox.mapboxsdk.geometry.LatLng;
-abstract class MapboxLatLngAnimator<L> extends MapboxAnimator<LatLng, L> {
+class MapboxLatLngAnimator extends MapboxAnimator<LatLng> {
- MapboxLatLngAnimator(LatLng previous, LatLng target, List<L> updateListeners) {
- super(previous, target, updateListeners);
+ MapboxLatLngAnimator(LatLng previous, LatLng target, AnimationsValueChangeListener updateListener,
+ int maxAnimationFps) {
+ super(previous, target, updateListener, maxAnimationFps);
}
@NonNull
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/OnRenderModeChangedListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/OnRenderModeChangedListener.java
new file mode 100644
index 0000000000..1ac016c8f3
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/OnRenderModeChangedListener.java
@@ -0,0 +1,16 @@
+package com.mapbox.mapboxsdk.location;
+
+import com.mapbox.mapboxsdk.location.modes.RenderMode;
+
+/**
+ * Listener that gets invoked when layer render mode changes.
+ */
+interface OnRenderModeChangedListener {
+
+ /**
+ * Invoked on every {@link RenderMode} change.
+ *
+ * @param currentMode current active {@link RenderMode}.
+ */
+ void onRenderModeChanged(@RenderMode.Mode int currentMode);
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/TiltAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/TiltAnimator.java
deleted file mode 100644
index 640ce0a678..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/TiltAnimator.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.animation.ValueAnimator;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-
-import java.util.List;
-
-class TiltAnimator extends MapboxCameraAnimatorAdapter {
- TiltAnimator(Float previous, Float target, List<OnCameraAnimationsValuesChangeListener> updateListeners,
- @Nullable MapboxMap.CancelableCallback cancelableCallback) {
- super(previous, target, updateListeners, cancelableCallback);
- }
-
- @Override
- int provideAnimatorType() {
- return ANIMATOR_TILT;
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- for (OnCameraAnimationsValuesChangeListener listener : updateListeners) {
- listener.onNewTiltValue((Float) animation.getAnimatedValue());
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/ZoomAnimator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/ZoomAnimator.java
deleted file mode 100644
index e37dfc1113..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/ZoomAnimator.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.mapbox.mapboxsdk.location;
-
-import android.animation.ValueAnimator;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-
-import java.util.List;
-
-class ZoomAnimator extends MapboxCameraAnimatorAdapter {
-
- ZoomAnimator(Float previous, Float target, List<OnCameraAnimationsValuesChangeListener> updateListeners,
- @Nullable MapboxMap.CancelableCallback cancelableCallback) {
- super(previous, target, updateListeners, cancelableCallback);
- }
-
- @Override
- int provideAnimatorType() {
- return ANIMATOR_ZOOM;
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- for (OnCameraAnimationsValuesChangeListener listener : updateListeners) {
- listener.onNewZoomValue((Float) animation.getAnimatedValue());
- }
- }
-}