diff options
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 |
commit | add96bebe14017da84b08a5a7f83be6f2fbd7e5c (patch) | |
tree | b9ec563cb60cb57a4267a7aa309784718d4dce9f | |
parent | 472e61da39a3e01d8b7a482d8e5c4351c905055b (diff) | |
download | qtlocation-mapboxgl-add96bebe14017da84b08a5a7f83be6f2fbd7e5c.tar.gz |
[android] optimize location animators memory footprint and add animation rate throttle option
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()); - } - } -} |