From 53d638de23c9fcd4207f1ed244ae16c0eac87183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 11 Jul 2018 19:05:47 +0200 Subject: [PATCH 01/10] [LLP] - added inheritance to LatLng animators --- .../locationlayer/CameraLatLngAnimator.java | 25 + .../plugins/locationlayer/LatLngAnimator.java | 19 + .../locationlayer/LatLngEvaluator.java | 19 + .../locationlayer/LayerLatLngAnimator.java | 25 + .../locationlayer/LocationLayerAnimator.java | 453 ++---------------- .../LocationLayerAnimatorCoordinator.java | 441 +++++++++++++++++ .../locationlayer/LocationLayerPlugin.java | 18 +- .../locationlayer/camera/LatLngAnimator.java | 36 -- 8 files changed, 574 insertions(+), 462 deletions(-) create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraLatLngAnimator.java create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngAnimator.java create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngEvaluator.java create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerLatLngAnimator.java create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimatorCoordinator.java delete mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraLatLngAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraLatLngAnimator.java new file mode 100644 index 000000000..0ede45c72 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraLatLngAnimator.java @@ -0,0 +1,25 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; + +import com.mapbox.mapboxsdk.geometry.LatLng; + +import java.util.List; + +class CameraLatLngAnimator extends LatLngAnimator { + CameraLatLngAnimator(LatLng previous, LatLng target, List updateListeners) { + super(previous, target, updateListeners); + } + + @Override + int provideAnimatorType() { + return ANIMATOR_CAMERA_LATLNG; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (OnCameraAnimationsValuesChangeListener listener : updateListeners) { + listener.onNewLatLngValue((LatLng) animation.getAnimatedValue()); + } + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngAnimator.java new file mode 100644 index 000000000..d3dea7628 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngAnimator.java @@ -0,0 +1,19 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.TypeEvaluator; + +import com.mapbox.mapboxsdk.geometry.LatLng; + +import java.util.List; + +abstract class LatLngAnimator extends LocationLayerAnimator { + + LatLngAnimator(LatLng previous, LatLng target, List updateListeners) { + super(previous, target, updateListeners); + } + + @Override + TypeEvaluator provideEvaluator() { + return new LatLngEvaluator(); + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngEvaluator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngEvaluator.java new file mode 100644 index 000000000..b137ea013 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngEvaluator.java @@ -0,0 +1,19 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.TypeEvaluator; + +import com.mapbox.mapboxsdk.geometry.LatLng; + +class LatLngEvaluator implements TypeEvaluator { + + private final LatLng latLng = new LatLng(); + + @Override + public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) { + latLng.setLatitude(startValue.getLatitude() + + ((endValue.getLatitude() - startValue.getLatitude()) * fraction)); + latLng.setLongitude(startValue.getLongitude() + + ((endValue.getLongitude() - startValue.getLongitude()) * fraction)); + return latLng; + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerLatLngAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerLatLngAnimator.java new file mode 100644 index 000000000..83d993fac --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerLatLngAnimator.java @@ -0,0 +1,25 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; + +import com.mapbox.mapboxsdk.geometry.LatLng; + +import java.util.List; + +class LayerLatLngAnimator extends LatLngAnimator { + LayerLatLngAnimator(LatLng previous, LatLng target, List updateListeners) { + super(previous, target, updateListeners); + } + + @Override + int provideAnimatorType() { + return ANIMATOR_LAYER_LATLNG; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (OnLayerAnimationsValuesChangeListener listener : updateListeners) { + listener.onNewLatLngValue((LatLng) animation.getAnimatedValue()); + } + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java index eb345031d..9e96d4605 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java @@ -1,183 +1,58 @@ package com.mapbox.mapboxsdk.plugins.locationlayer; -import android.animation.Animator; -import android.animation.AnimatorSet; +import android.animation.TypeEvaluator; import android.animation.ValueAnimator; -import android.location.Location; -import android.os.SystemClock; -import android.support.annotation.NonNull; -import android.view.animation.LinearInterpolator; +import android.support.annotation.IntDef; -import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.plugins.locationlayer.camera.AccuracyAnimator; -import com.mapbox.mapboxsdk.plugins.locationlayer.camera.BearingAnimator; -import com.mapbox.mapboxsdk.plugins.locationlayer.camera.LatLngAnimator; -import java.util.ArrayList; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.List; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.ACCURACY_RADIUS_ANIMATION_DURATION; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.COMPASS_UPDATE_RATE_MS; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.MAX_ANIMATION_DURATION_MS; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.TRANSITION_ANIMATION_DURATION_MS; - -final class LocationLayerAnimator { - - private final List layerListeners = new ArrayList<>(); - private final List cameraListeners = new ArrayList<>(); - - private LatLngAnimator layerLatLngAnimator; - private BearingAnimator layerGpsBearingAnimator; - private BearingAnimator layerCompassBearingAnimator; - private AccuracyAnimator accuracyRadiusAnimator; - - private LatLngAnimator cameraLatLngAnimator; - private BearingAnimator cameraGpsBearingAnimator; - private BearingAnimator cameraCompassBearingAnimator; - - private Location previousLocation; - private float previousAccuracyRadius = -1; - private float previousCompassBearing = -1; - private long locationUpdateTimestamp = -1; - - void addLayerListener(OnLayerAnimationsValuesChangeListener listener) { - layerListeners.add(listener); +/** + * Abstract class for all of the plugin animators. + * + * @param Data type that will be animated. + * @param Listener of animation updates. + */ +abstract class LocationLayerAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener { + @Retention(RetentionPolicy.SOURCE) + @IntDef( { + ANIMATOR_LAYER_LATLNG, + ANIMATOR_CAMERA_LATLNG + }) + @interface Type { } - void removeLayerListener(OnLayerAnimationsValuesChangeListener listener) { - layerListeners.remove(listener); - } + static final int ANIMATOR_LAYER_LATLNG = 0; + static final int ANIMATOR_CAMERA_LATLNG = 1; - void addCameraListener(OnCameraAnimationsValuesChangeListener listener) { - cameraListeners.add(listener); - } + private final int animatorType = provideAnimatorType(); + final List updateListeners; + private final K target; - void removeCameraListener(OnCameraAnimationsValuesChangeListener listener) { - cameraListeners.remove(listener); + LocationLayerAnimator(K previous, K target, List updateListeners) { + setObjectValues(previous, target); + setEvaluator(provideEvaluator()); + this.updateListeners = updateListeners; + this.target = target; + addUpdateListener(this); } - void feedNewLocation(@NonNull Location newLocation, @NonNull CameraPosition currentCameraPosition, - boolean isGpsNorth) { - if (previousLocation == null) { - previousLocation = newLocation; - locationUpdateTimestamp = SystemClock.elapsedRealtime(); - } - - LatLng previousLayerLatLng = getPreviousLayerLatLng(); - float previousLayerBearing = getPreviousLayerGpsBearing(); - LatLng previousCameraLatLng = currentCameraPosition.target; - float previousCameraBearing = (float) currentCameraPosition.bearing; - - LatLng targetLatLng = new LatLng(newLocation); - float targetLayerBearing = newLocation.getBearing(); - float targetCameraBearing = newLocation.getBearing(); - targetCameraBearing = checkGpsNorth(isGpsNorth, targetCameraBearing); - - updateLayerAnimators(previousLayerLatLng, targetLatLng, previousLayerBearing, targetLayerBearing); - updateCameraAnimators(previousCameraLatLng, previousCameraBearing, targetLatLng, targetCameraBearing); - - playAllLocationAnimators(getAnimationDuration()); - - previousLocation = newLocation; + K getTarget() { + return target; } - void feedNewCompassBearing(float targetCompassBearing, @NonNull CameraPosition currentCameraPosition) { - if (previousCompassBearing < 0) { - previousCompassBearing = targetCompassBearing; - } - - float previousLayerBearing = getPreviousLayerCompassBearing(); - float previousCameraBearing = (float) currentCameraPosition.bearing; - - updateCompassAnimators(targetCompassBearing, previousLayerBearing, previousCameraBearing); - playCompassAnimators(COMPASS_UPDATE_RATE_MS); - - previousCompassBearing = targetCompassBearing; + @Type + int getAnimatorType() { + return animatorType; } - void feedNewAccuracyRadius(float targetAccuracyRadius, boolean noAnimation) { - if (previousAccuracyRadius < 0) { - previousAccuracyRadius = targetAccuracyRadius; - } - - float previousAccuracyRadius = getPreviousAccuracyRadius(); - updateAccuracyAnimators(targetAccuracyRadius, previousAccuracyRadius); - accuracyRadiusAnimator.setDuration(noAnimation ? 0 : ACCURACY_RADIUS_ANIMATION_DURATION); - accuracyRadiusAnimator.start(); - - this.previousAccuracyRadius = targetAccuracyRadius; - } - - private final ValueAnimator.AnimatorUpdateListener layerLatLngUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnLayerAnimationsValuesChangeListener listener : layerListeners) { - listener.onNewLatLngValue((LatLng) valueAnimator.getAnimatedValue()); - } - } - }; - - private final ValueAnimator.AnimatorUpdateListener layerCompassBearingUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnLayerAnimationsValuesChangeListener listener : layerListeners) { - listener.onNewCompassBearingValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; - - private final ValueAnimator.AnimatorUpdateListener layerGpsBearingUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnLayerAnimationsValuesChangeListener listener : layerListeners) { - listener.onNewGpsBearingValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; - - private final ValueAnimator.AnimatorUpdateListener accuracyRadiusUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnLayerAnimationsValuesChangeListener listener : layerListeners) { - listener.onNewAccuracyRadiusValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; + @Type + abstract int provideAnimatorType(); - private final ValueAnimator.AnimatorUpdateListener cameraLatLngUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnCameraAnimationsValuesChangeListener listener : cameraListeners) { - listener.onNewLatLngValue((LatLng) valueAnimator.getAnimatedValue()); - } - } - }; - - private final ValueAnimator.AnimatorUpdateListener cameraCompassBearingUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnCameraAnimationsValuesChangeListener listener : cameraListeners) { - listener.onNewCompassBearingValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; - - private final ValueAnimator.AnimatorUpdateListener cameraGpsBearingUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (OnCameraAnimationsValuesChangeListener listener : cameraListeners) { - listener.onNewGpsBearingValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; + abstract TypeEvaluator provideEvaluator(); interface OnLayerAnimationsValuesChangeListener { void onNewLatLngValue(LatLng latLng); @@ -196,260 +71,4 @@ interface OnCameraAnimationsValuesChangeListener { void onNewCompassBearingValue(float compassBearing); } - - void resetAllCameraAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { - resetCameraCompassAnimation(currentCameraPosition); - resetCameraLocationAnimations(currentCameraPosition, isGpsNorth); - playCameraAnimators(TRANSITION_ANIMATION_DURATION_MS); - } - - void cancelAllAnimations() { - cancelLayerLocationAnimations(); - cancelLayerCompassAnimations(); - cancelAccuracyRadiusAnimations(); - cancelCameraLocationAnimations(); - cancelCameraCompassAnimations(); - } - - private LatLng getPreviousLayerLatLng() { - LatLng previousLatLng; - if (layerLatLngAnimator != null) { - previousLatLng = (LatLng) layerLatLngAnimator.getAnimatedValue(); - } else { - previousLatLng = new LatLng(previousLocation); - } - return previousLatLng; - } - - private float getPreviousLayerGpsBearing() { - float previousBearing; - if (layerGpsBearingAnimator != null) { - previousBearing = (float) layerGpsBearingAnimator.getAnimatedValue(); - } else { - previousBearing = previousLocation.getBearing(); - } - return previousBearing; - } - - private float getPreviousAccuracyRadius() { - float previousRadius; - if (accuracyRadiusAnimator != null) { - previousRadius = (float) accuracyRadiusAnimator.getAnimatedValue(); - } else { - previousRadius = previousAccuracyRadius; - } - return previousRadius; - } - - private float getPreviousLayerCompassBearing() { - float previousBearing; - if (layerCompassBearingAnimator != null) { - previousBearing = (float) layerCompassBearingAnimator.getAnimatedValue(); - } else { - previousBearing = previousCompassBearing; - } - return previousBearing; - } - - private void updateLayerAnimators(LatLng previousLatLng, LatLng targetLatLng, - float previousBearing, float targetBearing) { - cancelLayerLocationAnimations(); - layerLatLngAnimator = new LatLngAnimator(previousLatLng, targetLatLng); - float normalizedLayerBearing = Utils.shortestRotation(targetBearing, previousBearing); - layerGpsBearingAnimator = new BearingAnimator(previousBearing, normalizedLayerBearing); - - layerLatLngAnimator.addUpdateListener(layerLatLngUpdateListener); - layerGpsBearingAnimator.addUpdateListener(layerGpsBearingUpdateListener); - } - - private void updateCameraAnimators(LatLng previousCameraLatLng, float previousCameraBearing, - LatLng targetLatLng, float targetBearing) { - cancelCameraLocationAnimations(); - cameraLatLngAnimator = new LatLngAnimator(previousCameraLatLng, targetLatLng); - cameraLatLngAnimator.addUpdateListener(cameraLatLngUpdateListener); - - float normalizedCameraBearing = Utils.shortestRotation(targetBearing, previousCameraBearing); - cameraGpsBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); - cameraGpsBearingAnimator.addUpdateListener(cameraGpsBearingUpdateListener); - } - - private long getAnimationDuration() { - long previousUpdateTimeStamp = locationUpdateTimestamp; - locationUpdateTimestamp = SystemClock.elapsedRealtime(); - - long animationDuration; - if (previousUpdateTimeStamp == 0) { - animationDuration = 0; - } else { - animationDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1f) - /*make animation slightly longer*/; - } - - animationDuration = Math.min(animationDuration, MAX_ANIMATION_DURATION_MS); - - return animationDuration; - } - - private float checkGpsNorth(boolean isGpsNorth, float targetCameraBearing) { - if (isGpsNorth) { - targetCameraBearing = 0; - } - return targetCameraBearing; - } - - private void playAllLocationAnimators(long duration) { - List locationAnimators = new ArrayList<>(); - locationAnimators.add(layerLatLngAnimator); - locationAnimators.add(layerGpsBearingAnimator); - locationAnimators.add(cameraLatLngAnimator); - locationAnimators.add(cameraGpsBearingAnimator); - AnimatorSet locationAnimatorSet = new AnimatorSet(); - locationAnimatorSet.playTogether(locationAnimators); - locationAnimatorSet.setInterpolator(new LinearInterpolator()); - locationAnimatorSet.setDuration(duration); - locationAnimatorSet.start(); - } - - private void playCameraAnimators(long duration) { - List locationAnimators = new ArrayList<>(); - locationAnimators.add(cameraLatLngAnimator); - locationAnimators.add(cameraGpsBearingAnimator); - AnimatorSet locationAnimatorSet = new AnimatorSet(); - locationAnimatorSet.playTogether(locationAnimators); - locationAnimatorSet.setInterpolator(new LinearInterpolator()); - locationAnimatorSet.setDuration(duration); - locationAnimatorSet.start(); - } - - private void updateCompassAnimators(float targetCompassBearing, float previousLayerBearing, - float previousCameraBearing) { - cancelLayerCompassAnimations(); - float normalizedLayerBearing = Utils.shortestRotation(targetCompassBearing, previousLayerBearing); - layerCompassBearingAnimator = new BearingAnimator(previousLayerBearing, normalizedLayerBearing); - layerCompassBearingAnimator.addUpdateListener(layerCompassBearingUpdateListener); - - cancelCameraCompassAnimations(); - float normalizedCameraBearing = Utils.shortestRotation(targetCompassBearing, previousCameraBearing); - cameraCompassBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); - cameraCompassBearingAnimator.addUpdateListener(cameraCompassBearingUpdateListener); - } - - private void playCompassAnimators(long duration) { - List compassAnimators = new ArrayList<>(); - compassAnimators.add(layerCompassBearingAnimator); - compassAnimators.add(cameraCompassBearingAnimator); - AnimatorSet compassAnimatorSet = new AnimatorSet(); - compassAnimatorSet.playTogether(compassAnimators); - compassAnimatorSet.setDuration(duration); - compassAnimatorSet.start(); - } - - private void updateAccuracyAnimators(float targetAccuracyRadius, float previousAccuracyRadius) { - cancelAccuracyRadiusAnimations(); - accuracyRadiusAnimator = new AccuracyAnimator(previousAccuracyRadius, targetAccuracyRadius); - accuracyRadiusAnimator.addUpdateListener(accuracyRadiusUpdateListener); - } - - private void playAccuracyRadiusAnimation(long duration) { - } - - private void cancelLayerLocationAnimations() { - cancelLayerLatLngAnimations(); - cancelLayerGpsBearingAnimations(); - } - - private void cancelLayerLatLngAnimations() { - if (layerLatLngAnimator != null) { - layerLatLngAnimator.cancel(); - layerLatLngAnimator.removeAllUpdateListeners(); - } - } - - private void cancelLayerGpsBearingAnimations() { - if (layerGpsBearingAnimator != null) { - layerGpsBearingAnimator.cancel(); - layerGpsBearingAnimator.removeAllUpdateListeners(); - } - } - - private void cancelAccuracyRadiusAnimations() { - if (accuracyRadiusAnimator != null) { - accuracyRadiusAnimator.cancel(); - accuracyRadiusAnimator.removeAllUpdateListeners(); - } - } - - private void cancelLayerCompassAnimations() { - if (layerCompassBearingAnimator != null) { - layerCompassBearingAnimator.cancel(); - layerCompassBearingAnimator.removeAllUpdateListeners(); - } - } - - private void cancelCameraLocationAnimations() { - cancelCameraLatLngAnimations(); - cancelCameraGpsBearingAnimations(); - } - - private void resetCameraLocationAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { - resetCameraLatLngAnimation(currentCameraPosition); - resetCameraGpsBearingAnimation(currentCameraPosition, isGpsNorth); - } - - private void cancelCameraLatLngAnimations() { - if (cameraLatLngAnimator != null) { - cameraLatLngAnimator.cancel(); - cameraLatLngAnimator.removeAllUpdateListeners(); - } - } - - private void resetCameraLatLngAnimation(CameraPosition currentCameraPosition) { - if (cameraLatLngAnimator == null) { - return; - } - cancelCameraLatLngAnimations(); - LatLng currentTarget = cameraLatLngAnimator.getTarget(); - LatLng previousCameraTarget = currentCameraPosition.target; - cameraLatLngAnimator = new LatLngAnimator(previousCameraTarget, currentTarget); - cameraLatLngAnimator.addUpdateListener(cameraLatLngUpdateListener); - } - - private void cancelCameraGpsBearingAnimations() { - if (cameraGpsBearingAnimator != null) { - cameraGpsBearingAnimator.cancel(); - cameraGpsBearingAnimator.removeAllUpdateListeners(); - } - } - - private void resetCameraGpsBearingAnimation(CameraPosition currentCameraPosition, boolean isGpsNorth) { - if (cameraGpsBearingAnimator == null) { - return; - } - cancelCameraGpsBearingAnimations(); - float currentTargetBearing = cameraGpsBearingAnimator.getTargetBearing(); - currentTargetBearing = checkGpsNorth(isGpsNorth, currentTargetBearing); - float previousCameraBearing = (float) currentCameraPosition.bearing; - float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); - cameraGpsBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); - cameraGpsBearingAnimator.addUpdateListener(cameraGpsBearingUpdateListener); - } - - private void cancelCameraCompassAnimations() { - if (cameraCompassBearingAnimator != null) { - cameraCompassBearingAnimator.cancel(); - cameraCompassBearingAnimator.removeAllUpdateListeners(); - } - } - - private void resetCameraCompassAnimation(CameraPosition currentCameraPosition) { - if (cameraCompassBearingAnimator == null || cameraLatLngAnimator == null) { - return; - } - cancelCameraCompassAnimations(); - float currentTargetBearing = cameraCompassBearingAnimator.getTargetBearing(); - float previousCameraBearing = (float) currentCameraPosition.bearing; - float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); - cameraCompassBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); - cameraCompassBearingAnimator.addUpdateListener(cameraCompassBearingUpdateListener); - } } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimatorCoordinator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimatorCoordinator.java new file mode 100644 index 000000000..544345f25 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimatorCoordinator.java @@ -0,0 +1,441 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.animation.ValueAnimator; +import android.annotation.SuppressLint; +import android.location.Location; +import android.os.SystemClock; +import android.support.annotation.NonNull; +import android.view.animation.LinearInterpolator; + +import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.plugins.locationlayer.camera.AccuracyAnimator; +import com.mapbox.mapboxsdk.plugins.locationlayer.camera.BearingAnimator; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerAnimator.ANIMATOR_CAMERA_LATLNG; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerAnimator.ANIMATOR_LAYER_LATLNG; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.ACCURACY_RADIUS_ANIMATION_DURATION; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.COMPASS_UPDATE_RATE_MS; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.MAX_ANIMATION_DURATION_MS; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.TRANSITION_ANIMATION_DURATION_MS; + +final class LocationLayerAnimatorCoordinator { + + @SuppressLint("UseSparseArrays") + private final Map animatorMap = new HashMap<>(); + + private final List layerListeners = new ArrayList<>(); + private final List cameraListeners = new ArrayList<>(); + + private BearingAnimator layerGpsBearingAnimator; + private BearingAnimator layerCompassBearingAnimator; + private AccuracyAnimator accuracyRadiusAnimator; + + private BearingAnimator cameraGpsBearingAnimator; + private BearingAnimator cameraCompassBearingAnimator; + + private Location previousLocation; + private float previousAccuracyRadius = -1; + private float previousCompassBearing = -1; + private long locationUpdateTimestamp = -1; + + void addLayerListener(LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener) { + layerListeners.add(listener); + } + + void removeLayerListener(LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener) { + layerListeners.remove(listener); + } + + void addCameraListener(LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener) { + cameraListeners.add(listener); + } + + void removeCameraListener(LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener) { + cameraListeners.remove(listener); + } + + void feedNewLocation(@NonNull Location newLocation, @NonNull CameraPosition currentCameraPosition, + boolean isGpsNorth) { + if (previousLocation == null) { + previousLocation = newLocation; + locationUpdateTimestamp = SystemClock.elapsedRealtime(); + } + + LatLng previousLayerLatLng = getPreviousLayerLatLng(); + float previousLayerBearing = getPreviousLayerGpsBearing(); + LatLng previousCameraLatLng = currentCameraPosition.target; + float previousCameraBearing = (float) currentCameraPosition.bearing; + + LatLng targetLatLng = new LatLng(newLocation); + float targetLayerBearing = newLocation.getBearing(); + float targetCameraBearing = newLocation.getBearing(); + targetCameraBearing = checkGpsNorth(isGpsNorth, targetCameraBearing); + + updateLayerAnimators(previousLayerLatLng, targetLatLng, previousLayerBearing, targetLayerBearing); + updateCameraAnimators(previousCameraLatLng, previousCameraBearing, targetLatLng, targetCameraBearing); + + playAllLocationAnimators(getAnimationDuration()); + + previousLocation = newLocation; + } + + void feedNewCompassBearing(float targetCompassBearing, @NonNull CameraPosition currentCameraPosition) { + if (previousCompassBearing < 0) { + previousCompassBearing = targetCompassBearing; + } + + float previousLayerBearing = getPreviousLayerCompassBearing(); + float previousCameraBearing = (float) currentCameraPosition.bearing; + + updateCompassAnimators(targetCompassBearing, previousLayerBearing, previousCameraBearing); + playCompassAnimators(COMPASS_UPDATE_RATE_MS); + + previousCompassBearing = targetCompassBearing; + } + + void feedNewAccuracyRadius(float targetAccuracyRadius, boolean noAnimation) { + if (previousAccuracyRadius < 0) { + previousAccuracyRadius = targetAccuracyRadius; + } + + float previousAccuracyRadius = getPreviousAccuracyRadius(); + updateAccuracyAnimators(targetAccuracyRadius, previousAccuracyRadius); + accuracyRadiusAnimator.setDuration(noAnimation ? 0 : ACCURACY_RADIUS_ANIMATION_DURATION); + accuracyRadiusAnimator.start(); + + this.previousAccuracyRadius = targetAccuracyRadius; + } + + private final ValueAnimator.AnimatorUpdateListener layerLatLngUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { + listener.onNewLatLngValue((LatLng) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener layerCompassBearingUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { + listener.onNewCompassBearingValue((Float) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener layerGpsBearingUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { + listener.onNewGpsBearingValue((Float) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener accuracyRadiusUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { + listener.onNewAccuracyRadiusValue((Float) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener cameraLatLngUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener : cameraListeners) { + listener.onNewLatLngValue((LatLng) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener cameraCompassBearingUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener : cameraListeners) { + listener.onNewCompassBearingValue((Float) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener cameraGpsBearingUpdateListener = + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener : cameraListeners) { + listener.onNewGpsBearingValue((Float) valueAnimator.getAnimatedValue()); + } + } + }; + + void resetAllCameraAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { + resetCameraCompassAnimation(currentCameraPosition); + resetCameraLocationAnimations(currentCameraPosition, isGpsNorth); + playCameraAnimators(TRANSITION_ANIMATION_DURATION_MS); + } + + void cancelAllAnimations() { + cancelLayerLocationAnimations(); + cancelLayerCompassAnimations(); + cancelAccuracyRadiusAnimations(); + cancelCameraLocationAnimations(); + cancelCameraCompassAnimations(); + } + + private LatLng getPreviousLayerLatLng() { + LatLng previousLatLng; + LocationLayerAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); + if (latLngAnimator != null) { + previousLatLng = (LatLng) latLngAnimator.getAnimatedValue(); + } else { + previousLatLng = new LatLng(previousLocation); + } + return previousLatLng; + } + + private float getPreviousLayerGpsBearing() { + float previousBearing; + if (layerGpsBearingAnimator != null) { + previousBearing = (float) layerGpsBearingAnimator.getAnimatedValue(); + } else { + previousBearing = previousLocation.getBearing(); + } + return previousBearing; + } + + private float getPreviousAccuracyRadius() { + float previousRadius; + if (accuracyRadiusAnimator != null) { + previousRadius = (float) accuracyRadiusAnimator.getAnimatedValue(); + } else { + previousRadius = previousAccuracyRadius; + } + return previousRadius; + } + + private float getPreviousLayerCompassBearing() { + float previousBearing; + if (layerCompassBearingAnimator != null) { + previousBearing = (float) layerCompassBearingAnimator.getAnimatedValue(); + } else { + previousBearing = previousCompassBearing; + } + return previousBearing; + } + + private void updateLayerAnimators(LatLng previousLatLng, LatLng targetLatLng, + float previousBearing, float targetBearing) { + cancelLayerLocationAnimations(); + animatorMap.put(ANIMATOR_LAYER_LATLNG, new LayerLatLngAnimator(previousLatLng, targetLatLng, layerListeners)); + float normalizedLayerBearing = Utils.shortestRotation(targetBearing, previousBearing); + layerGpsBearingAnimator = new BearingAnimator(previousBearing, normalizedLayerBearing); + + layerGpsBearingAnimator.addUpdateListener(layerGpsBearingUpdateListener); + } + + private void updateCameraAnimators(LatLng previousCameraLatLng, float previousCameraBearing, + LatLng targetLatLng, float targetBearing) { + cancelCameraLocationAnimations(); + animatorMap.put(ANIMATOR_CAMERA_LATLNG, new CameraLatLngAnimator(previousCameraLatLng, targetLatLng, cameraListeners)); + + float normalizedCameraBearing = Utils.shortestRotation(targetBearing, previousCameraBearing); + cameraGpsBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); + cameraGpsBearingAnimator.addUpdateListener(cameraGpsBearingUpdateListener); + } + + private long getAnimationDuration() { + long previousUpdateTimeStamp = locationUpdateTimestamp; + locationUpdateTimestamp = SystemClock.elapsedRealtime(); + + long animationDuration; + if (previousUpdateTimeStamp == 0) { + animationDuration = 0; + } else { + animationDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1f) + /*make animation slightly longer*/; + } + + animationDuration = Math.min(animationDuration, MAX_ANIMATION_DURATION_MS); + + return animationDuration; + } + + private float checkGpsNorth(boolean isGpsNorth, float targetCameraBearing) { + if (isGpsNorth) { + targetCameraBearing = 0; + } + return targetCameraBearing; + } + + private void playAllLocationAnimators(long duration) { + List locationAnimators = new ArrayList<>(); + locationAnimators.add(animatorMap.get(ANIMATOR_LAYER_LATLNG)); + locationAnimators.add(layerGpsBearingAnimator); + locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_LATLNG)); + locationAnimators.add(cameraGpsBearingAnimator); + AnimatorSet locationAnimatorSet = new AnimatorSet(); + locationAnimatorSet.playTogether(locationAnimators); + locationAnimatorSet.setInterpolator(new LinearInterpolator()); + locationAnimatorSet.setDuration(duration); + locationAnimatorSet.start(); + } + + private void playCameraAnimators(long duration) { + List locationAnimators = new ArrayList<>(); + locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_LATLNG)); + locationAnimators.add(cameraGpsBearingAnimator); + AnimatorSet locationAnimatorSet = new AnimatorSet(); + locationAnimatorSet.playTogether(locationAnimators); + locationAnimatorSet.setInterpolator(new LinearInterpolator()); + locationAnimatorSet.setDuration(duration); + locationAnimatorSet.start(); + } + + private void updateCompassAnimators(float targetCompassBearing, float previousLayerBearing, + float previousCameraBearing) { + cancelLayerCompassAnimations(); + float normalizedLayerBearing = Utils.shortestRotation(targetCompassBearing, previousLayerBearing); + layerCompassBearingAnimator = new BearingAnimator(previousLayerBearing, normalizedLayerBearing); + layerCompassBearingAnimator.addUpdateListener(layerCompassBearingUpdateListener); + + cancelCameraCompassAnimations(); + float normalizedCameraBearing = Utils.shortestRotation(targetCompassBearing, previousCameraBearing); + cameraCompassBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); + cameraCompassBearingAnimator.addUpdateListener(cameraCompassBearingUpdateListener); + } + + private void playCompassAnimators(long duration) { + List compassAnimators = new ArrayList<>(); + compassAnimators.add(layerCompassBearingAnimator); + compassAnimators.add(cameraCompassBearingAnimator); + AnimatorSet compassAnimatorSet = new AnimatorSet(); + compassAnimatorSet.playTogether(compassAnimators); + compassAnimatorSet.setDuration(duration); + compassAnimatorSet.start(); + } + + private void updateAccuracyAnimators(float targetAccuracyRadius, float previousAccuracyRadius) { + cancelAccuracyRadiusAnimations(); + accuracyRadiusAnimator = new AccuracyAnimator(previousAccuracyRadius, targetAccuracyRadius); + accuracyRadiusAnimator.addUpdateListener(accuracyRadiusUpdateListener); + } + + private void cancelLayerLocationAnimations() { + cancelLayerLatLngAnimations(); + cancelLayerGpsBearingAnimations(); + } + + private void cancelLayerLatLngAnimations() { + LocationLayerAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); + if (latLngAnimator != null) { + latLngAnimator.cancel(); + latLngAnimator.removeAllUpdateListeners(); + } + } + + private void cancelLayerGpsBearingAnimations() { + if (layerGpsBearingAnimator != null) { + layerGpsBearingAnimator.cancel(); + layerGpsBearingAnimator.removeAllUpdateListeners(); + } + } + + private void cancelAccuracyRadiusAnimations() { + if (accuracyRadiusAnimator != null) { + accuracyRadiusAnimator.cancel(); + accuracyRadiusAnimator.removeAllUpdateListeners(); + } + } + + private void cancelLayerCompassAnimations() { + if (layerCompassBearingAnimator != null) { + layerCompassBearingAnimator.cancel(); + layerCompassBearingAnimator.removeAllUpdateListeners(); + } + } + + private void cancelCameraLocationAnimations() { + cancelCameraLatLngAnimations(); + cancelCameraGpsBearingAnimations(); + } + + private void resetCameraLocationAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { + resetCameraLatLngAnimation(currentCameraPosition); + resetCameraGpsBearingAnimation(currentCameraPosition, isGpsNorth); + } + + private void cancelCameraLatLngAnimations() { + LocationLayerAnimator latLngAnimator = animatorMap.get(ANIMATOR_CAMERA_LATLNG); + if (latLngAnimator != null) { + latLngAnimator.cancel(); + latLngAnimator.removeAllUpdateListeners(); + } + } + + private void resetCameraLatLngAnimation(CameraPosition currentCameraPosition) { + CameraLatLngAnimator cameraLatLngAnimator = (CameraLatLngAnimator) animatorMap.get(ANIMATOR_CAMERA_LATLNG); + if (cameraLatLngAnimator == null) { + return; + } + cancelCameraLatLngAnimations(); + LatLng currentTarget = cameraLatLngAnimator.getTarget(); + LatLng previousCameraTarget = currentCameraPosition.target; + animatorMap.put(ANIMATOR_CAMERA_LATLNG, new CameraLatLngAnimator(previousCameraTarget, currentTarget, cameraListeners)); + } + + private void cancelCameraGpsBearingAnimations() { + if (cameraGpsBearingAnimator != null) { + cameraGpsBearingAnimator.cancel(); + cameraGpsBearingAnimator.removeAllUpdateListeners(); + } + } + + private void resetCameraGpsBearingAnimation(CameraPosition currentCameraPosition, boolean isGpsNorth) { + if (cameraGpsBearingAnimator == null) { + return; + } + cancelCameraGpsBearingAnimations(); + float currentTargetBearing = cameraGpsBearingAnimator.getTargetBearing(); + currentTargetBearing = checkGpsNorth(isGpsNorth, currentTargetBearing); + float previousCameraBearing = (float) currentCameraPosition.bearing; + float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); + cameraGpsBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); + cameraGpsBearingAnimator.addUpdateListener(cameraGpsBearingUpdateListener); + } + + private void cancelCameraCompassAnimations() { + if (cameraCompassBearingAnimator != null) { + cameraCompassBearingAnimator.cancel(); + cameraCompassBearingAnimator.removeAllUpdateListeners(); + } + } + + private void resetCameraCompassAnimation(CameraPosition currentCameraPosition) { + CameraLatLngAnimator cameraLatLngAnimator = (CameraLatLngAnimator) animatorMap.get(ANIMATOR_CAMERA_LATLNG); + if (cameraCompassBearingAnimator == null || cameraLatLngAnimator == null) { + return; + } + cancelCameraCompassAnimations(); + float currentTargetBearing = cameraCompassBearingAnimator.getTargetBearing(); + float previousCameraBearing = (float) currentCameraPosition.bearing; + float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); + cameraCompassBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); + cameraCompassBearingAnimator.addUpdateListener(cameraCompassBearingUpdateListener); + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index 2c39a4a8a..1b27b7e0e 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -71,7 +71,7 @@ public final class LocationLayerPlugin implements LifecycleObserver { private LocationLayer locationLayer; private LocationLayerCamera locationLayerCamera; - private LocationLayerAnimator locationLayerAnimator; + private LocationLayerAnimatorCoordinator locationLayerAnimatorCoordinator; /** * Holds last location which is being returned in the {@link #getLastKnownLocation()} @@ -222,7 +222,7 @@ public boolean isLocationLayerEnabled() { */ public void setCameraMode(@CameraMode.Mode int cameraMode) { boolean isGpsNorth = cameraMode == CameraMode.TRACKING_GPS_NORTH; - locationLayerAnimator.resetAllCameraAnimations(mapboxMap.getCameraPosition(), isGpsNorth); + locationLayerAnimatorCoordinator.resetAllCameraAnimations(mapboxMap.getCameraPosition(), isGpsNorth); locationLayerCamera.setCameraMode(cameraMode); } @@ -535,7 +535,7 @@ void onLocationLayerStop() { locationLayer.hide(); staleStateManager.onStop(); compassManager.onStop(); - locationLayerAnimator.cancelAllAnimations(); + locationLayerAnimatorCoordinator.cancelAllAnimations(); if (locationEngine != null) { locationEngine.removeLocationEngineListener(locationEngineListener); } @@ -556,9 +556,9 @@ private void initialize() { locationLayer = new LocationLayer(mapView, mapboxMap, options); locationLayerCamera = new LocationLayerCamera( mapView.getContext(), mapboxMap, cameraTrackingChangedListener, options, onCameraMoveInvalidateListener); - locationLayerAnimator = new LocationLayerAnimator(); - locationLayerAnimator.addLayerListener(locationLayer); - locationLayerAnimator.addCameraListener(locationLayerCamera); + locationLayerAnimatorCoordinator = new LocationLayerAnimatorCoordinator(); + locationLayerAnimatorCoordinator.addLayerListener(locationLayer); + locationLayerAnimatorCoordinator.addCameraListener(locationLayerCamera); compassManager = new CompassManager(mapView.getContext()); compassManager.addCompassListener(compassListener); @@ -615,13 +615,13 @@ private void updateLocation(final Location location) { staleStateManager.updateLatestLocationTime(); CameraPosition currentCameraPosition = mapboxMap.getCameraPosition(); boolean isGpsNorth = getCameraMode() == CameraMode.TRACKING_GPS_NORTH; - locationLayerAnimator.feedNewLocation(location, currentCameraPosition, isGpsNorth); + locationLayerAnimatorCoordinator.feedNewLocation(location, currentCameraPosition, isGpsNorth); updateAccuracyRadius(location, false); lastLocation = location; } private void updateCompassHeading(float heading) { - locationLayerAnimator.feedNewCompassBearing(heading, mapboxMap.getCameraPosition()); + locationLayerAnimatorCoordinator.feedNewCompassBearing(heading, mapboxMap.getCameraPosition()); } /** @@ -663,7 +663,7 @@ private void updateLayerOffsets(boolean forceUpdate) { } private void updateAccuracyRadius(Location location, boolean noAnimation) { - locationLayerAnimator.feedNewAccuracyRadius(Utils.calculateZoomLevelRadius(mapboxMap, location), noAnimation); + locationLayerAnimatorCoordinator.feedNewAccuracyRadius(Utils.calculateZoomLevelRadius(mapboxMap, location), noAnimation); } private OnCameraMoveListener onCameraMoveListener = new OnCameraMoveListener() { diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java deleted file mode 100644 index 243d9890d..000000000 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.locationlayer.camera; - -import android.animation.TypeEvaluator; -import android.animation.ValueAnimator; -import android.support.annotation.NonNull; - -import com.mapbox.mapboxsdk.geometry.LatLng; - -public class LatLngAnimator extends ValueAnimator { - - private LatLng target; - - public LatLngAnimator(@NonNull LatLng previous, @NonNull LatLng target) { - setObjectValues(previous, target); - setEvaluator(new LatLngEvaluator()); - this.target = target; - } - - public LatLng getTarget() { - return target; - } - - private static class LatLngEvaluator implements TypeEvaluator { - - private final LatLng latLng = new LatLng(); - - @Override - public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) { - latLng.setLatitude(startValue.getLatitude() - + ((endValue.getLatitude() - startValue.getLatitude()) * fraction)); - latLng.setLongitude(startValue.getLongitude() - + ((endValue.getLongitude() - startValue.getLongitude()) * fraction)); - return latLng; - } - } -} From 049781eee9c2959ebc13d33035359b0ec8dd3ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 12 Jul 2018 13:03:57 +0200 Subject: [PATCH 02/10] [LLP] - added inheritance to bearing animators --- .../CameraCompassBearingAnimator.java | 23 +++ .../CameraGpsBearingAnimator.java | 23 +++ .../locationlayer/CameraLatLngAnimator.java | 2 +- .../LayerCompassBearingAnimator.java | 23 +++ .../LayerGpsBearingAnimator.java | 23 +++ .../locationlayer/LayerLatLngAnimator.java | 2 +- .../plugins/locationlayer/LocationLayer.java | 2 +- .../locationlayer/LocationLayerCamera.java | 2 +- .../locationlayer/LocationLayerPlugin.java | 18 +- ...LayerAnimator.java => PluginAnimator.java} | 14 +- ...or.java => PluginAnimatorCoordinator.java} | 173 ++++++------------ .../locationlayer/PluginFloatAnimator.java | 17 ++ ...nimator.java => PluginLatLngAnimator.java} | 4 +- .../locationlayer/camera/BearingAnimator.java | 19 -- 14 files changed, 187 insertions(+), 158 deletions(-) create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraCompassBearingAnimator.java create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraGpsBearingAnimator.java create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerCompassBearingAnimator.java create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerGpsBearingAnimator.java rename plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/{LocationLayerAnimator.java => PluginAnimator.java} (75%) rename plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/{LocationLayerAnimatorCoordinator.java => PluginAnimatorCoordinator.java} (64%) create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginFloatAnimator.java rename plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/{LatLngAnimator.java => PluginLatLngAnimator.java} (66%) delete mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraCompassBearingAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraCompassBearingAnimator.java new file mode 100644 index 000000000..65de60ef2 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraCompassBearingAnimator.java @@ -0,0 +1,23 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; + +import java.util.List; + +class CameraCompassBearingAnimator extends PluginFloatAnimator { + CameraCompassBearingAnimator(Float previous, Float target, List updateListeners) { + super(previous, target, updateListeners); + } + + @Override + int provideAnimatorType() { + return ANIMATOR_CAMERA_COMPASS_BEARING; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (OnCameraAnimationsValuesChangeListener listener : updateListeners) { + listener.onNewCompassBearingValue((Float) animation.getAnimatedValue()); + } + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraGpsBearingAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraGpsBearingAnimator.java new file mode 100644 index 000000000..ac88a0258 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraGpsBearingAnimator.java @@ -0,0 +1,23 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; + +import java.util.List; + +class CameraGpsBearingAnimator extends PluginFloatAnimator { + CameraGpsBearingAnimator(Float previous, Float target, List updateListeners) { + super(previous, target, updateListeners); + } + + @Override + int provideAnimatorType() { + return ANIMATOR_CAMERA_GPS_BEARING; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (OnCameraAnimationsValuesChangeListener listener : updateListeners) { + listener.onNewGpsBearingValue((Float) animation.getAnimatedValue()); + } + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraLatLngAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraLatLngAnimator.java index 0ede45c72..6f383a480 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraLatLngAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraLatLngAnimator.java @@ -6,7 +6,7 @@ import java.util.List; -class CameraLatLngAnimator extends LatLngAnimator { +class CameraLatLngAnimator extends PluginLatLngAnimator { CameraLatLngAnimator(LatLng previous, LatLng target, List updateListeners) { super(previous, target, updateListeners); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerCompassBearingAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerCompassBearingAnimator.java new file mode 100644 index 000000000..8f298502d --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerCompassBearingAnimator.java @@ -0,0 +1,23 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; + +import java.util.List; + +class LayerCompassBearingAnimator extends PluginFloatAnimator { + LayerCompassBearingAnimator(Float previous, Float target, List updateListeners) { + super(previous, target, updateListeners); + } + + @Override + int provideAnimatorType() { + return ANIMATOR_LAYER_COMPASS_BEARING; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (OnLayerAnimationsValuesChangeListener listener : updateListeners) { + listener.onNewCompassBearingValue((Float) animation.getAnimatedValue()); + } + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerGpsBearingAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerGpsBearingAnimator.java new file mode 100644 index 000000000..c14ffbb93 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerGpsBearingAnimator.java @@ -0,0 +1,23 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; + +import java.util.List; + +class LayerGpsBearingAnimator extends PluginFloatAnimator { + LayerGpsBearingAnimator(Float previous, Float target, List updateListeners) { + super(previous, target, updateListeners); + } + + @Override + int provideAnimatorType() { + return ANIMATOR_LAYER_GPS_BEARING; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (OnLayerAnimationsValuesChangeListener listener : updateListeners) { + listener.onNewGpsBearingValue((Float) animation.getAnimatedValue()); + } + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerLatLngAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerLatLngAnimator.java index 83d993fac..0ff0a46bd 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerLatLngAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerLatLngAnimator.java @@ -6,7 +6,7 @@ import java.util.List; -class LayerLatLngAnimator extends LatLngAnimator { +class LayerLatLngAnimator extends PluginLatLngAnimator { LayerLatLngAnimator(LatLng previous, LatLng target, List updateListeners) { super(previous, target, updateListeners); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index d24fc9ec7..35c139798 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java @@ -81,7 +81,7 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility; -final class LocationLayer implements LocationLayerAnimator.OnLayerAnimationsValuesChangeListener { +final class LocationLayer implements PluginAnimator.OnLayerAnimationsValuesChangeListener { @RenderMode.Mode private int renderMode; diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java index 194fc3353..819d1aa60 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java @@ -15,7 +15,7 @@ import java.util.List; import java.util.Set; -final class LocationLayerCamera implements LocationLayerAnimator.OnCameraAnimationsValuesChangeListener { +final class LocationLayerCamera implements PluginAnimator.OnCameraAnimationsValuesChangeListener { @CameraMode.Mode private int cameraMode; diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index 1b27b7e0e..d82705061 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -71,7 +71,7 @@ public final class LocationLayerPlugin implements LifecycleObserver { private LocationLayer locationLayer; private LocationLayerCamera locationLayerCamera; - private LocationLayerAnimatorCoordinator locationLayerAnimatorCoordinator; + private PluginAnimatorCoordinator pluginAnimatorCoordinator; /** * Holds last location which is being returned in the {@link #getLastKnownLocation()} @@ -222,7 +222,7 @@ public boolean isLocationLayerEnabled() { */ public void setCameraMode(@CameraMode.Mode int cameraMode) { boolean isGpsNorth = cameraMode == CameraMode.TRACKING_GPS_NORTH; - locationLayerAnimatorCoordinator.resetAllCameraAnimations(mapboxMap.getCameraPosition(), isGpsNorth); + pluginAnimatorCoordinator.resetAllCameraAnimations(mapboxMap.getCameraPosition(), isGpsNorth); locationLayerCamera.setCameraMode(cameraMode); } @@ -535,7 +535,7 @@ void onLocationLayerStop() { locationLayer.hide(); staleStateManager.onStop(); compassManager.onStop(); - locationLayerAnimatorCoordinator.cancelAllAnimations(); + pluginAnimatorCoordinator.cancelAllAnimations(); if (locationEngine != null) { locationEngine.removeLocationEngineListener(locationEngineListener); } @@ -556,9 +556,9 @@ private void initialize() { locationLayer = new LocationLayer(mapView, mapboxMap, options); locationLayerCamera = new LocationLayerCamera( mapView.getContext(), mapboxMap, cameraTrackingChangedListener, options, onCameraMoveInvalidateListener); - locationLayerAnimatorCoordinator = new LocationLayerAnimatorCoordinator(); - locationLayerAnimatorCoordinator.addLayerListener(locationLayer); - locationLayerAnimatorCoordinator.addCameraListener(locationLayerCamera); + pluginAnimatorCoordinator = new PluginAnimatorCoordinator(); + pluginAnimatorCoordinator.addLayerListener(locationLayer); + pluginAnimatorCoordinator.addCameraListener(locationLayerCamera); compassManager = new CompassManager(mapView.getContext()); compassManager.addCompassListener(compassListener); @@ -615,13 +615,13 @@ private void updateLocation(final Location location) { staleStateManager.updateLatestLocationTime(); CameraPosition currentCameraPosition = mapboxMap.getCameraPosition(); boolean isGpsNorth = getCameraMode() == CameraMode.TRACKING_GPS_NORTH; - locationLayerAnimatorCoordinator.feedNewLocation(location, currentCameraPosition, isGpsNorth); + pluginAnimatorCoordinator.feedNewLocation(location, currentCameraPosition, isGpsNorth); updateAccuracyRadius(location, false); lastLocation = location; } private void updateCompassHeading(float heading) { - locationLayerAnimatorCoordinator.feedNewCompassBearing(heading, mapboxMap.getCameraPosition()); + pluginAnimatorCoordinator.feedNewCompassBearing(heading, mapboxMap.getCameraPosition()); } /** @@ -663,7 +663,7 @@ private void updateLayerOffsets(boolean forceUpdate) { } private void updateAccuracyRadius(Location location, boolean noAnimation) { - locationLayerAnimatorCoordinator.feedNewAccuracyRadius(Utils.calculateZoomLevelRadius(mapboxMap, location), noAnimation); + pluginAnimatorCoordinator.feedNewAccuracyRadius(Utils.calculateZoomLevelRadius(mapboxMap, location), noAnimation); } private OnCameraMoveListener onCameraMoveListener = new OnCameraMoveListener() { diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java similarity index 75% rename from plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java rename to plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java index 9e96d4605..b6786b608 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java @@ -16,23 +16,31 @@ * @param Data type that will be animated. * @param Listener of animation updates. */ -abstract class LocationLayerAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener { +abstract class PluginAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener { @Retention(RetentionPolicy.SOURCE) @IntDef( { ANIMATOR_LAYER_LATLNG, - ANIMATOR_CAMERA_LATLNG + ANIMATOR_CAMERA_LATLNG, + ANIMATOR_LAYER_GPS_BEARING, + ANIMATOR_LAYER_COMPASS_BEARING, + ANIMATOR_CAMERA_GPS_BEARING, + ANIMATOR_CAMERA_COMPASS_BEARING }) @interface Type { } static final int ANIMATOR_LAYER_LATLNG = 0; static final int ANIMATOR_CAMERA_LATLNG = 1; + static final int ANIMATOR_LAYER_GPS_BEARING = 2; + static final int ANIMATOR_LAYER_COMPASS_BEARING = 3; + static final int ANIMATOR_CAMERA_GPS_BEARING = 4; + static final int ANIMATOR_CAMERA_COMPASS_BEARING = 5; private final int animatorType = provideAnimatorType(); final List updateListeners; private final K target; - LocationLayerAnimator(K previous, K target, List updateListeners) { + PluginAnimator(K previous, K target, List updateListeners) { setObjectValues(previous, target); setEvaluator(provideEvaluator()); this.updateListeners = updateListeners; diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimatorCoordinator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java similarity index 64% rename from plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimatorCoordinator.java rename to plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java index 544345f25..bd238edcf 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimatorCoordinator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java @@ -12,53 +12,51 @@ import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.plugins.locationlayer.camera.AccuracyAnimator; -import com.mapbox.mapboxsdk.plugins.locationlayer.camera.BearingAnimator; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerAnimator.ANIMATOR_CAMERA_LATLNG; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerAnimator.ANIMATOR_LAYER_LATLNG; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.ACCURACY_RADIUS_ANIMATION_DURATION; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.COMPASS_UPDATE_RATE_MS; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.MAX_ANIMATION_DURATION_MS; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.TRANSITION_ANIMATION_DURATION_MS; +import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_CAMERA_COMPASS_BEARING; +import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_CAMERA_GPS_BEARING; +import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_CAMERA_LATLNG; +import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_COMPASS_BEARING; +import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_GPS_BEARING; +import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_LATLNG; -final class LocationLayerAnimatorCoordinator { +final class PluginAnimatorCoordinator { @SuppressLint("UseSparseArrays") - private final Map animatorMap = new HashMap<>(); + private final Map animatorMap = new HashMap<>(); - private final List layerListeners = new ArrayList<>(); - private final List cameraListeners = new ArrayList<>(); + private final List layerListeners = new ArrayList<>(); + private final List cameraListeners = new ArrayList<>(); - private BearingAnimator layerGpsBearingAnimator; - private BearingAnimator layerCompassBearingAnimator; private AccuracyAnimator accuracyRadiusAnimator; - private BearingAnimator cameraGpsBearingAnimator; - private BearingAnimator cameraCompassBearingAnimator; - private Location previousLocation; private float previousAccuracyRadius = -1; private float previousCompassBearing = -1; private long locationUpdateTimestamp = -1; - void addLayerListener(LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener) { + void addLayerListener(PluginAnimator.OnLayerAnimationsValuesChangeListener listener) { layerListeners.add(listener); } - void removeLayerListener(LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener) { + void removeLayerListener(PluginAnimator.OnLayerAnimationsValuesChangeListener listener) { layerListeners.remove(listener); } - void addCameraListener(LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener) { + void addCameraListener(PluginAnimator.OnCameraAnimationsValuesChangeListener listener) { cameraListeners.add(listener); } - void removeCameraListener(LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener) { + void removeCameraListener(PluginAnimator.OnCameraAnimationsValuesChangeListener listener) { cameraListeners.remove(listener); } @@ -114,76 +112,16 @@ void feedNewAccuracyRadius(float targetAccuracyRadius, boolean noAnimation) { this.previousAccuracyRadius = targetAccuracyRadius; } - private final ValueAnimator.AnimatorUpdateListener layerLatLngUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { - listener.onNewLatLngValue((LatLng) valueAnimator.getAnimatedValue()); - } - } - }; - - private final ValueAnimator.AnimatorUpdateListener layerCompassBearingUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { - listener.onNewCompassBearingValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; - - private final ValueAnimator.AnimatorUpdateListener layerGpsBearingUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { - listener.onNewGpsBearingValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; - private final ValueAnimator.AnimatorUpdateListener accuracyRadiusUpdateListener = new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (LocationLayerAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { + for (PluginAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { listener.onNewAccuracyRadiusValue((Float) valueAnimator.getAnimatedValue()); } } }; - private final ValueAnimator.AnimatorUpdateListener cameraLatLngUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener : cameraListeners) { - listener.onNewLatLngValue((LatLng) valueAnimator.getAnimatedValue()); - } - } - }; - - private final ValueAnimator.AnimatorUpdateListener cameraCompassBearingUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener : cameraListeners) { - listener.onNewCompassBearingValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; - - private final ValueAnimator.AnimatorUpdateListener cameraGpsBearingUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (LocationLayerAnimator.OnCameraAnimationsValuesChangeListener listener : cameraListeners) { - listener.onNewGpsBearingValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; - void resetAllCameraAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { resetCameraCompassAnimation(currentCameraPosition); resetCameraLocationAnimations(currentCameraPosition, isGpsNorth); @@ -200,7 +138,7 @@ void cancelAllAnimations() { private LatLng getPreviousLayerLatLng() { LatLng previousLatLng; - LocationLayerAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); + PluginAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); if (latLngAnimator != null) { previousLatLng = (LatLng) latLngAnimator.getAnimatedValue(); } else { @@ -210,9 +148,10 @@ private LatLng getPreviousLayerLatLng() { } private float getPreviousLayerGpsBearing() { + LayerGpsBearingAnimator animator = (LayerGpsBearingAnimator) animatorMap.get(ANIMATOR_LAYER_GPS_BEARING); float previousBearing; - if (layerGpsBearingAnimator != null) { - previousBearing = (float) layerGpsBearingAnimator.getAnimatedValue(); + if (animator != null) { + previousBearing = (float) animator.getAnimatedValue(); } else { previousBearing = previousLocation.getBearing(); } @@ -230,9 +169,10 @@ private float getPreviousAccuracyRadius() { } private float getPreviousLayerCompassBearing() { + LayerCompassBearingAnimator animator = (LayerCompassBearingAnimator) animatorMap.get(ANIMATOR_LAYER_COMPASS_BEARING); float previousBearing; - if (layerCompassBearingAnimator != null) { - previousBearing = (float) layerCompassBearingAnimator.getAnimatedValue(); + if (animator != null) { + previousBearing = (float) animator.getAnimatedValue(); } else { previousBearing = previousCompassBearing; } @@ -244,9 +184,7 @@ private void updateLayerAnimators(LatLng previousLatLng, LatLng targetLatLng, cancelLayerLocationAnimations(); animatorMap.put(ANIMATOR_LAYER_LATLNG, new LayerLatLngAnimator(previousLatLng, targetLatLng, layerListeners)); float normalizedLayerBearing = Utils.shortestRotation(targetBearing, previousBearing); - layerGpsBearingAnimator = new BearingAnimator(previousBearing, normalizedLayerBearing); - - layerGpsBearingAnimator.addUpdateListener(layerGpsBearingUpdateListener); + animatorMap.put(ANIMATOR_LAYER_GPS_BEARING, new LayerGpsBearingAnimator(previousBearing, normalizedLayerBearing, layerListeners)); } private void updateCameraAnimators(LatLng previousCameraLatLng, float previousCameraBearing, @@ -255,8 +193,7 @@ private void updateCameraAnimators(LatLng previousCameraLatLng, float previousCa animatorMap.put(ANIMATOR_CAMERA_LATLNG, new CameraLatLngAnimator(previousCameraLatLng, targetLatLng, cameraListeners)); float normalizedCameraBearing = Utils.shortestRotation(targetBearing, previousCameraBearing); - cameraGpsBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); - cameraGpsBearingAnimator.addUpdateListener(cameraGpsBearingUpdateListener); + animatorMap.put(ANIMATOR_CAMERA_GPS_BEARING, new CameraGpsBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); } private long getAnimationDuration() { @@ -286,9 +223,9 @@ private float checkGpsNorth(boolean isGpsNorth, float targetCameraBearing) { private void playAllLocationAnimators(long duration) { List locationAnimators = new ArrayList<>(); locationAnimators.add(animatorMap.get(ANIMATOR_LAYER_LATLNG)); - locationAnimators.add(layerGpsBearingAnimator); + locationAnimators.add(animatorMap.get(ANIMATOR_LAYER_GPS_BEARING)); locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_LATLNG)); - locationAnimators.add(cameraGpsBearingAnimator); + locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_GPS_BEARING)); AnimatorSet locationAnimatorSet = new AnimatorSet(); locationAnimatorSet.playTogether(locationAnimators); locationAnimatorSet.setInterpolator(new LinearInterpolator()); @@ -299,7 +236,7 @@ private void playAllLocationAnimators(long duration) { private void playCameraAnimators(long duration) { List locationAnimators = new ArrayList<>(); locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_LATLNG)); - locationAnimators.add(cameraGpsBearingAnimator); + locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_GPS_BEARING)); AnimatorSet locationAnimatorSet = new AnimatorSet(); locationAnimatorSet.playTogether(locationAnimators); locationAnimatorSet.setInterpolator(new LinearInterpolator()); @@ -311,19 +248,17 @@ private void updateCompassAnimators(float targetCompassBearing, float previousLa float previousCameraBearing) { cancelLayerCompassAnimations(); float normalizedLayerBearing = Utils.shortestRotation(targetCompassBearing, previousLayerBearing); - layerCompassBearingAnimator = new BearingAnimator(previousLayerBearing, normalizedLayerBearing); - layerCompassBearingAnimator.addUpdateListener(layerCompassBearingUpdateListener); + animatorMap.put(ANIMATOR_LAYER_COMPASS_BEARING, new LayerCompassBearingAnimator(previousLayerBearing, normalizedLayerBearing, layerListeners)); cancelCameraCompassAnimations(); float normalizedCameraBearing = Utils.shortestRotation(targetCompassBearing, previousCameraBearing); - cameraCompassBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); - cameraCompassBearingAnimator.addUpdateListener(cameraCompassBearingUpdateListener); + animatorMap.put(ANIMATOR_CAMERA_COMPASS_BEARING, new CameraCompassBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); } private void playCompassAnimators(long duration) { List compassAnimators = new ArrayList<>(); - compassAnimators.add(layerCompassBearingAnimator); - compassAnimators.add(cameraCompassBearingAnimator); + compassAnimators.add(animatorMap.get(ANIMATOR_LAYER_COMPASS_BEARING)); + compassAnimators.add(animatorMap.get(ANIMATOR_CAMERA_COMPASS_BEARING)); AnimatorSet compassAnimatorSet = new AnimatorSet(); compassAnimatorSet.playTogether(compassAnimators); compassAnimatorSet.setDuration(duration); @@ -342,7 +277,7 @@ private void cancelLayerLocationAnimations() { } private void cancelLayerLatLngAnimations() { - LocationLayerAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); + PluginAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); if (latLngAnimator != null) { latLngAnimator.cancel(); latLngAnimator.removeAllUpdateListeners(); @@ -350,10 +285,7 @@ private void cancelLayerLatLngAnimations() { } private void cancelLayerGpsBearingAnimations() { - if (layerGpsBearingAnimator != null) { - layerGpsBearingAnimator.cancel(); - layerGpsBearingAnimator.removeAllUpdateListeners(); - } + cancelAnimator(PluginAnimator.ANIMATOR_LAYER_GPS_BEARING); } private void cancelAccuracyRadiusAnimations() { @@ -364,10 +296,7 @@ private void cancelAccuracyRadiusAnimations() { } private void cancelLayerCompassAnimations() { - if (layerCompassBearingAnimator != null) { - layerCompassBearingAnimator.cancel(); - layerCompassBearingAnimator.removeAllUpdateListeners(); - } + cancelAnimator(PluginAnimator.ANIMATOR_LAYER_COMPASS_BEARING); } private void cancelCameraLocationAnimations() { @@ -381,7 +310,7 @@ private void resetCameraLocationAnimations(CameraPosition currentCameraPosition, } private void cancelCameraLatLngAnimations() { - LocationLayerAnimator latLngAnimator = animatorMap.get(ANIMATOR_CAMERA_LATLNG); + PluginAnimator latLngAnimator = animatorMap.get(ANIMATOR_CAMERA_LATLNG); if (latLngAnimator != null) { latLngAnimator.cancel(); latLngAnimator.removeAllUpdateListeners(); @@ -400,42 +329,44 @@ private void resetCameraLatLngAnimation(CameraPosition currentCameraPosition) { } private void cancelCameraGpsBearingAnimations() { - if (cameraGpsBearingAnimator != null) { - cameraGpsBearingAnimator.cancel(); - cameraGpsBearingAnimator.removeAllUpdateListeners(); - } + cancelAnimator(PluginAnimator.ANIMATOR_CAMERA_GPS_BEARING); } private void resetCameraGpsBearingAnimation(CameraPosition currentCameraPosition, boolean isGpsNorth) { - if (cameraGpsBearingAnimator == null) { + CameraGpsBearingAnimator animator = (CameraGpsBearingAnimator) animatorMap.get(ANIMATOR_CAMERA_GPS_BEARING); + if (animator == null) { return; } cancelCameraGpsBearingAnimations(); - float currentTargetBearing = cameraGpsBearingAnimator.getTargetBearing(); + float currentTargetBearing = animator.getTarget(); currentTargetBearing = checkGpsNorth(isGpsNorth, currentTargetBearing); float previousCameraBearing = (float) currentCameraPosition.bearing; float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); - cameraGpsBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); - cameraGpsBearingAnimator.addUpdateListener(cameraGpsBearingUpdateListener); + animatorMap.put(ANIMATOR_CAMERA_GPS_BEARING, new CameraGpsBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); } private void cancelCameraCompassAnimations() { - if (cameraCompassBearingAnimator != null) { - cameraCompassBearingAnimator.cancel(); - cameraCompassBearingAnimator.removeAllUpdateListeners(); - } + cancelAnimator(PluginAnimator.ANIMATOR_CAMERA_COMPASS_BEARING); } private void resetCameraCompassAnimation(CameraPosition currentCameraPosition) { CameraLatLngAnimator cameraLatLngAnimator = (CameraLatLngAnimator) animatorMap.get(ANIMATOR_CAMERA_LATLNG); + CameraCompassBearingAnimator cameraCompassBearingAnimator = (CameraCompassBearingAnimator) animatorMap.get(ANIMATOR_CAMERA_COMPASS_BEARING); if (cameraCompassBearingAnimator == null || cameraLatLngAnimator == null) { return; } cancelCameraCompassAnimations(); - float currentTargetBearing = cameraCompassBearingAnimator.getTargetBearing(); + float currentTargetBearing = cameraCompassBearingAnimator.getTarget(); float previousCameraBearing = (float) currentCameraPosition.bearing; float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); - cameraCompassBearingAnimator = new BearingAnimator(previousCameraBearing, normalizedCameraBearing); - cameraCompassBearingAnimator.addUpdateListener(cameraCompassBearingUpdateListener); + animatorMap.put(ANIMATOR_CAMERA_COMPASS_BEARING, new CameraCompassBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); + } + + private void cancelAnimator(@PluginAnimator.Type int animatorType) { + PluginAnimator animator = animatorMap.get(animatorType); + if (animator != null) { + animator.cancel(); + animator.removeAllUpdateListeners(); + } } } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginFloatAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginFloatAnimator.java new file mode 100644 index 000000000..f99f17cd9 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginFloatAnimator.java @@ -0,0 +1,17 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.FloatEvaluator; +import android.animation.TypeEvaluator; + +import java.util.List; + +abstract class PluginFloatAnimator extends PluginAnimator { + PluginFloatAnimator(Float previous, Float target, List updateListeners) { + super(previous, target, updateListeners); + } + + @Override + TypeEvaluator provideEvaluator() { + return new FloatEvaluator(); + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginLatLngAnimator.java similarity index 66% rename from plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngAnimator.java rename to plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginLatLngAnimator.java index d3dea7628..29d73f8db 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LatLngAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginLatLngAnimator.java @@ -6,9 +6,9 @@ import java.util.List; -abstract class LatLngAnimator extends LocationLayerAnimator { +abstract class PluginLatLngAnimator extends PluginAnimator { - LatLngAnimator(LatLng previous, LatLng target, List updateListeners) { + PluginLatLngAnimator(LatLng previous, LatLng target, List updateListeners) { super(previous, target, updateListeners); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java deleted file mode 100644 index 53ec82454..000000000 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.locationlayer.camera; - -import android.animation.FloatEvaluator; -import android.animation.ValueAnimator; - -public class BearingAnimator extends ValueAnimator { - - private float targetBearing; - - public BearingAnimator(float previous, float target) { - setEvaluator(new FloatEvaluator()); - setFloatValues(previous, target); - this.targetBearing = target; - } - - public float getTargetBearing() { - return targetBearing; - } -} From ff9e9afb2dbd6d3117a544e9cd9ddb42bb48f05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 12 Jul 2018 13:11:27 +0200 Subject: [PATCH 03/10] [LLP] - added inheritance to accuracy animator --- .../locationlayer/LayerAccuracyAnimator.java | 24 ++++++++++++ .../plugins/locationlayer/PluginAnimator.java | 4 +- .../PluginAnimatorCoordinator.java | 37 ++++++------------- .../camera/AccuracyAnimator.java | 12 ------ 4 files changed, 38 insertions(+), 39 deletions(-) create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerAccuracyAnimator.java delete mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/AccuracyAnimator.java diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerAccuracyAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerAccuracyAnimator.java new file mode 100644 index 000000000..1d200f454 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerAccuracyAnimator.java @@ -0,0 +1,24 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; + +import java.util.List; + +class LayerAccuracyAnimator extends PluginFloatAnimator { + + LayerAccuracyAnimator(Float previous, Float target, List updateListeners) { + super(previous, target, updateListeners); + } + + @Override + int provideAnimatorType() { + return ANIMATOR_LAYER_ACCURACY; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (OnLayerAnimationsValuesChangeListener listener : updateListeners) { + listener.onNewAccuracyRadiusValue((Float) animation.getAnimatedValue()); + } + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java index b6786b608..db229436a 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java @@ -24,7 +24,8 @@ abstract class PluginAnimator extends ValueAnimator implements ValueAnimat ANIMATOR_LAYER_GPS_BEARING, ANIMATOR_LAYER_COMPASS_BEARING, ANIMATOR_CAMERA_GPS_BEARING, - ANIMATOR_CAMERA_COMPASS_BEARING + ANIMATOR_CAMERA_COMPASS_BEARING, + ANIMATOR_LAYER_ACCURACY }) @interface Type { } @@ -35,6 +36,7 @@ abstract class PluginAnimator extends ValueAnimator implements ValueAnimat static final int ANIMATOR_LAYER_COMPASS_BEARING = 3; static final int ANIMATOR_CAMERA_GPS_BEARING = 4; static final int ANIMATOR_CAMERA_COMPASS_BEARING = 5; + static final int ANIMATOR_LAYER_ACCURACY = 6; private final int animatorType = provideAnimatorType(); final List updateListeners; diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java index bd238edcf..bd12b12c3 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java @@ -2,7 +2,6 @@ import android.animation.Animator; import android.animation.AnimatorSet; -import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.location.Location; import android.os.SystemClock; @@ -11,7 +10,6 @@ import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.plugins.locationlayer.camera.AccuracyAnimator; import java.util.ArrayList; import java.util.HashMap; @@ -25,6 +23,7 @@ import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_CAMERA_COMPASS_BEARING; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_CAMERA_GPS_BEARING; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_CAMERA_LATLNG; +import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_ACCURACY; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_COMPASS_BEARING; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_GPS_BEARING; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_LATLNG; @@ -37,8 +36,6 @@ final class PluginAnimatorCoordinator { private final List layerListeners = new ArrayList<>(); private final List cameraListeners = new ArrayList<>(); - private AccuracyAnimator accuracyRadiusAnimator; - private Location previousLocation; private float previousAccuracyRadius = -1; private float previousCompassBearing = -1; @@ -106,22 +103,13 @@ void feedNewAccuracyRadius(float targetAccuracyRadius, boolean noAnimation) { float previousAccuracyRadius = getPreviousAccuracyRadius(); updateAccuracyAnimators(targetAccuracyRadius, previousAccuracyRadius); - accuracyRadiusAnimator.setDuration(noAnimation ? 0 : ACCURACY_RADIUS_ANIMATION_DURATION); - accuracyRadiusAnimator.start(); + PluginAnimator animator = animatorMap.get(ANIMATOR_LAYER_ACCURACY); + animator.setDuration(noAnimation ? 0 : ACCURACY_RADIUS_ANIMATION_DURATION); + animator.start(); this.previousAccuracyRadius = targetAccuracyRadius; } - private final ValueAnimator.AnimatorUpdateListener accuracyRadiusUpdateListener = - new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - for (PluginAnimator.OnLayerAnimationsValuesChangeListener listener : layerListeners) { - listener.onNewAccuracyRadiusValue((Float) valueAnimator.getAnimatedValue()); - } - } - }; - void resetAllCameraAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { resetCameraCompassAnimation(currentCameraPosition); resetCameraLocationAnimations(currentCameraPosition, isGpsNorth); @@ -159,9 +147,10 @@ private float getPreviousLayerGpsBearing() { } private float getPreviousAccuracyRadius() { + LayerAccuracyAnimator animator = (LayerAccuracyAnimator) animatorMap.get(ANIMATOR_LAYER_ACCURACY); float previousRadius; - if (accuracyRadiusAnimator != null) { - previousRadius = (float) accuracyRadiusAnimator.getAnimatedValue(); + if (animator != null) { + previousRadius = (float) animator.getAnimatedValue(); } else { previousRadius = previousAccuracyRadius; } @@ -267,8 +256,7 @@ private void playCompassAnimators(long duration) { private void updateAccuracyAnimators(float targetAccuracyRadius, float previousAccuracyRadius) { cancelAccuracyRadiusAnimations(); - accuracyRadiusAnimator = new AccuracyAnimator(previousAccuracyRadius, targetAccuracyRadius); - accuracyRadiusAnimator.addUpdateListener(accuracyRadiusUpdateListener); + animatorMap.put(ANIMATOR_LAYER_ACCURACY, new LayerAccuracyAnimator(previousAccuracyRadius, targetAccuracyRadius, layerListeners)); } private void cancelLayerLocationAnimations() { @@ -285,18 +273,15 @@ private void cancelLayerLatLngAnimations() { } private void cancelLayerGpsBearingAnimations() { - cancelAnimator(PluginAnimator.ANIMATOR_LAYER_GPS_BEARING); + cancelAnimator(ANIMATOR_LAYER_GPS_BEARING); } private void cancelAccuracyRadiusAnimations() { - if (accuracyRadiusAnimator != null) { - accuracyRadiusAnimator.cancel(); - accuracyRadiusAnimator.removeAllUpdateListeners(); - } + cancelAnimator(ANIMATOR_LAYER_ACCURACY); } private void cancelLayerCompassAnimations() { - cancelAnimator(PluginAnimator.ANIMATOR_LAYER_COMPASS_BEARING); + cancelAnimator(ANIMATOR_LAYER_COMPASS_BEARING); } private void cancelCameraLocationAnimations() { diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/AccuracyAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/AccuracyAnimator.java deleted file mode 100644 index 37982978b..000000000 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/AccuracyAnimator.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.locationlayer.camera; - -import android.animation.FloatEvaluator; -import android.animation.ValueAnimator; - -public class AccuracyAnimator extends ValueAnimator { - - public AccuracyAnimator(float previous, float target) { - setEvaluator(new FloatEvaluator()); - setFloatValues(previous, target); - } -} \ No newline at end of file From 00c934a5cd2537e990e2501c336821ef38f21b4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 12 Jul 2018 13:52:43 +0200 Subject: [PATCH 04/10] [LLP] - cleaned up animators refactor --- .../locationlayer/LocationLayerPluginTest.kt | 110 ++++++++++ .../CameraCompassBearingAnimator.java | 3 +- .../LayerCompassBearingAnimator.java | 3 +- .../PluginAnimatorCoordinator.java | 201 ++++++++---------- 4 files changed, 199 insertions(+), 118 deletions(-) diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt index c11012bb4..d036e6ad6 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -23,6 +23,7 @@ import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.maps.SupportMapFragment import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.* +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode import com.mapbox.mapboxsdk.plugins.testapp.activity.SingleFragmentActivity import com.mapbox.mapboxsdk.plugins.utils.* @@ -638,6 +639,115 @@ class LocationLayerPluginTest { onView(withId(R.id.content)).check(matches(isDisplayed())) } + @Test + fun animators_layerBearingCorrect() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.GPS + location.bearing = 77f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(1000) + assertEquals(77.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) + + location.bearing = 92f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + assertEquals(92.0, mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getNumberProperty(PROPERTY_GPS_BEARING) as Double, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + + @Test + fun animators_cameraLatLngBearingCorrect() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING_GPS + location.bearing = 77f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(1000) + assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + + location.bearing = 92f + location.latitude = 30.0 + location.longitude = 35.0 + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + + @Test + fun animators_cameraBearingCorrect() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.NONE_GPS + val latitude = mapboxMap.cameraPosition.target.latitude + val longitude = mapboxMap.cameraPosition.target.longitude + + location.bearing = 77f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(1000) + assertEquals(77.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + + location.bearing = 92f + location.latitude = 30.0 + location.longitude = 35.0 + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + assertEquals(92.0, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + + @Test + fun animators_cameraNoneCorrect() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.NONE + val latitude = mapboxMap.cameraPosition.target.latitude + val longitude = mapboxMap.cameraPosition.target.longitude + val bearing = mapboxMap.cameraPosition.bearing + + location.bearing = 77f + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(1000) + assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + + location.bearing = 92f + location.latitude = 30.0 + location.longitude = 35.0 + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(2000) // Waiting for the animation to finish + assertEquals(bearing, mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + @After fun afterTest() { Timber.e("@After: unregister idle resource") diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraCompassBearingAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraCompassBearingAnimator.java index 65de60ef2..6d5fd9da8 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraCompassBearingAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CameraCompassBearingAnimator.java @@ -5,7 +5,8 @@ import java.util.List; class CameraCompassBearingAnimator extends PluginFloatAnimator { - CameraCompassBearingAnimator(Float previous, Float target, List updateListeners) { + CameraCompassBearingAnimator(Float previous, Float target, + List updateListeners) { super(previous, target, updateListeners); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerCompassBearingAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerCompassBearingAnimator.java index 8f298502d..3b3898d1e 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerCompassBearingAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LayerCompassBearingAnimator.java @@ -5,7 +5,8 @@ import java.util.List; class LayerCompassBearingAnimator extends PluginFloatAnimator { - LayerCompassBearingAnimator(Float previous, Float target, List updateListeners) { + LayerCompassBearingAnimator(Float previous, + Float target, List updateListeners) { super(previous, target, updateListeners); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java index bd12b12c3..1c85ec6fa 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java @@ -77,7 +77,7 @@ void feedNewLocation(@NonNull Location newLocation, @NonNull CameraPosition curr updateLayerAnimators(previousLayerLatLng, targetLatLng, previousLayerBearing, targetLayerBearing); updateCameraAnimators(previousCameraLatLng, previousCameraBearing, targetLatLng, targetCameraBearing); - playAllLocationAnimators(getAnimationDuration()); + playLocationAnimators(getAnimationDuration()); previousLocation = newLocation; } @@ -103,27 +103,11 @@ void feedNewAccuracyRadius(float targetAccuracyRadius, boolean noAnimation) { float previousAccuracyRadius = getPreviousAccuracyRadius(); updateAccuracyAnimators(targetAccuracyRadius, previousAccuracyRadius); - PluginAnimator animator = animatorMap.get(ANIMATOR_LAYER_ACCURACY); - animator.setDuration(noAnimation ? 0 : ACCURACY_RADIUS_ANIMATION_DURATION); - animator.start(); + playAccuracyAnimator(noAnimation ? 0 : ACCURACY_RADIUS_ANIMATION_DURATION); this.previousAccuracyRadius = targetAccuracyRadius; } - void resetAllCameraAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { - resetCameraCompassAnimation(currentCameraPosition); - resetCameraLocationAnimations(currentCameraPosition, isGpsNorth); - playCameraAnimators(TRANSITION_ANIMATION_DURATION_MS); - } - - void cancelAllAnimations() { - cancelLayerLocationAnimations(); - cancelLayerCompassAnimations(); - cancelAccuracyRadiusAnimations(); - cancelCameraLocationAnimations(); - cancelCameraCompassAnimations(); - } - private LatLng getPreviousLayerLatLng() { LatLng previousLatLng; PluginAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); @@ -146,6 +130,19 @@ private float getPreviousLayerGpsBearing() { return previousBearing; } + private float getPreviousLayerCompassBearing() { + LayerCompassBearingAnimator animator = + (LayerCompassBearingAnimator) animatorMap.get(ANIMATOR_LAYER_COMPASS_BEARING); + + float previousBearing; + if (animator != null) { + previousBearing = (float) animator.getAnimatedValue(); + } else { + previousBearing = previousCompassBearing; + } + return previousBearing; + } + private float getPreviousAccuracyRadius() { LayerAccuracyAnimator animator = (LayerAccuracyAnimator) animatorMap.get(ANIMATOR_LAYER_ACCURACY); float previousRadius; @@ -157,32 +154,39 @@ private float getPreviousAccuracyRadius() { return previousRadius; } - private float getPreviousLayerCompassBearing() { - LayerCompassBearingAnimator animator = (LayerCompassBearingAnimator) animatorMap.get(ANIMATOR_LAYER_COMPASS_BEARING); - float previousBearing; - if (animator != null) { - previousBearing = (float) animator.getAnimatedValue(); - } else { - previousBearing = previousCompassBearing; - } - return previousBearing; - } - private void updateLayerAnimators(LatLng previousLatLng, LatLng targetLatLng, float previousBearing, float targetBearing) { - cancelLayerLocationAnimations(); - animatorMap.put(ANIMATOR_LAYER_LATLNG, new LayerLatLngAnimator(previousLatLng, targetLatLng, layerListeners)); + createNewAnimator(ANIMATOR_LAYER_LATLNG, new LayerLatLngAnimator(previousLatLng, targetLatLng, layerListeners)); + float normalizedLayerBearing = Utils.shortestRotation(targetBearing, previousBearing); - animatorMap.put(ANIMATOR_LAYER_GPS_BEARING, new LayerGpsBearingAnimator(previousBearing, normalizedLayerBearing, layerListeners)); + createNewAnimator(ANIMATOR_LAYER_GPS_BEARING, + new LayerGpsBearingAnimator(previousBearing, normalizedLayerBearing, layerListeners)); } private void updateCameraAnimators(LatLng previousCameraLatLng, float previousCameraBearing, LatLng targetLatLng, float targetBearing) { - cancelCameraLocationAnimations(); - animatorMap.put(ANIMATOR_CAMERA_LATLNG, new CameraLatLngAnimator(previousCameraLatLng, targetLatLng, cameraListeners)); + createNewAnimator(ANIMATOR_CAMERA_LATLNG, + new CameraLatLngAnimator(previousCameraLatLng, targetLatLng, cameraListeners)); float normalizedCameraBearing = Utils.shortestRotation(targetBearing, previousCameraBearing); - animatorMap.put(ANIMATOR_CAMERA_GPS_BEARING, new CameraGpsBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); + createNewAnimator(ANIMATOR_CAMERA_GPS_BEARING, + new CameraGpsBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); + } + + 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)); + + float normalizedCameraBearing = Utils.shortestRotation(targetCompassBearing, previousCameraBearing); + createNewAnimator(ANIMATOR_CAMERA_COMPASS_BEARING, + new CameraCompassBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); + } + + private void updateAccuracyAnimators(float targetAccuracyRadius, float previousAccuracyRadius) { + createNewAnimator(ANIMATOR_LAYER_ACCURACY, + new LayerAccuracyAnimator(previousAccuracyRadius, targetAccuracyRadius, layerListeners)); } private long getAnimationDuration() { @@ -209,7 +213,7 @@ private float checkGpsNorth(boolean isGpsNorth, float targetCameraBearing) { return targetCameraBearing; } - private void playAllLocationAnimators(long duration) { + private void playLocationAnimators(long duration) { List locationAnimators = new ArrayList<>(); locationAnimators.add(animatorMap.get(ANIMATOR_LAYER_LATLNG)); locationAnimators.add(animatorMap.get(ANIMATOR_LAYER_GPS_BEARING)); @@ -222,28 +226,6 @@ private void playAllLocationAnimators(long duration) { locationAnimatorSet.start(); } - private void playCameraAnimators(long duration) { - List locationAnimators = new ArrayList<>(); - locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_LATLNG)); - locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_GPS_BEARING)); - AnimatorSet locationAnimatorSet = new AnimatorSet(); - locationAnimatorSet.playTogether(locationAnimators); - locationAnimatorSet.setInterpolator(new LinearInterpolator()); - locationAnimatorSet.setDuration(duration); - locationAnimatorSet.start(); - } - - private void updateCompassAnimators(float targetCompassBearing, float previousLayerBearing, - float previousCameraBearing) { - cancelLayerCompassAnimations(); - float normalizedLayerBearing = Utils.shortestRotation(targetCompassBearing, previousLayerBearing); - animatorMap.put(ANIMATOR_LAYER_COMPASS_BEARING, new LayerCompassBearingAnimator(previousLayerBearing, normalizedLayerBearing, layerListeners)); - - cancelCameraCompassAnimations(); - float normalizedCameraBearing = Utils.shortestRotation(targetCompassBearing, previousCameraBearing); - animatorMap.put(ANIMATOR_CAMERA_COMPASS_BEARING, new CameraCompassBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); - } - private void playCompassAnimators(long duration) { List compassAnimators = new ArrayList<>(); compassAnimators.add(animatorMap.get(ANIMATOR_LAYER_COMPASS_BEARING)); @@ -254,39 +236,27 @@ private void playCompassAnimators(long duration) { compassAnimatorSet.start(); } - private void updateAccuracyAnimators(float targetAccuracyRadius, float previousAccuracyRadius) { - cancelAccuracyRadiusAnimations(); - animatorMap.put(ANIMATOR_LAYER_ACCURACY, new LayerAccuracyAnimator(previousAccuracyRadius, targetAccuracyRadius, layerListeners)); - } - - private void cancelLayerLocationAnimations() { - cancelLayerLatLngAnimations(); - cancelLayerGpsBearingAnimations(); - } - - private void cancelLayerLatLngAnimations() { - PluginAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); - if (latLngAnimator != null) { - latLngAnimator.cancel(); - latLngAnimator.removeAllUpdateListeners(); - } - } - - private void cancelLayerGpsBearingAnimations() { - cancelAnimator(ANIMATOR_LAYER_GPS_BEARING); - } - - private void cancelAccuracyRadiusAnimations() { - cancelAnimator(ANIMATOR_LAYER_ACCURACY); + private void playAccuracyAnimator(long duration) { + PluginAnimator animator = animatorMap.get(ANIMATOR_LAYER_ACCURACY); + animator.setDuration(duration); + animator.start(); } - private void cancelLayerCompassAnimations() { - cancelAnimator(ANIMATOR_LAYER_COMPASS_BEARING); + private void playCameraLocationAnimators(long duration) { + List locationAnimators = new ArrayList<>(); + locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_LATLNG)); + locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_GPS_BEARING)); + AnimatorSet locationAnimatorSet = new AnimatorSet(); + locationAnimatorSet.playTogether(locationAnimators); + locationAnimatorSet.setInterpolator(new LinearInterpolator()); + locationAnimatorSet.setDuration(duration); + locationAnimatorSet.start(); } - private void cancelCameraLocationAnimations() { - cancelCameraLatLngAnimations(); - cancelCameraGpsBearingAnimations(); + void resetAllCameraAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { + resetCameraCompassAnimation(currentCameraPosition); + resetCameraLocationAnimations(currentCameraPosition, isGpsNorth); + playCameraLocationAnimators(TRANSITION_ANIMATION_DURATION_MS); } private void resetCameraLocationAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { @@ -294,27 +264,16 @@ private void resetCameraLocationAnimations(CameraPosition currentCameraPosition, resetCameraGpsBearingAnimation(currentCameraPosition, isGpsNorth); } - private void cancelCameraLatLngAnimations() { - PluginAnimator latLngAnimator = animatorMap.get(ANIMATOR_CAMERA_LATLNG); - if (latLngAnimator != null) { - latLngAnimator.cancel(); - latLngAnimator.removeAllUpdateListeners(); - } - } - private void resetCameraLatLngAnimation(CameraPosition currentCameraPosition) { - CameraLatLngAnimator cameraLatLngAnimator = (CameraLatLngAnimator) animatorMap.get(ANIMATOR_CAMERA_LATLNG); - if (cameraLatLngAnimator == null) { + CameraLatLngAnimator animator = (CameraLatLngAnimator) animatorMap.get(ANIMATOR_CAMERA_LATLNG); + if (animator == null) { return; } - cancelCameraLatLngAnimations(); - LatLng currentTarget = cameraLatLngAnimator.getTarget(); - LatLng previousCameraTarget = currentCameraPosition.target; - animatorMap.put(ANIMATOR_CAMERA_LATLNG, new CameraLatLngAnimator(previousCameraTarget, currentTarget, cameraListeners)); - } - private void cancelCameraGpsBearingAnimations() { - cancelAnimator(PluginAnimator.ANIMATOR_CAMERA_GPS_BEARING); + LatLng currentTarget = animator.getTarget(); + LatLng previousCameraTarget = currentCameraPosition.target; + createNewAnimator(ANIMATOR_CAMERA_LATLNG, + new CameraLatLngAnimator(previousCameraTarget, currentTarget, cameraListeners)); } private void resetCameraGpsBearingAnimation(CameraPosition currentCameraPosition, boolean isGpsNorth) { @@ -322,29 +281,38 @@ private void resetCameraGpsBearingAnimation(CameraPosition currentCameraPosition if (animator == null) { return; } - cancelCameraGpsBearingAnimations(); + float currentTargetBearing = animator.getTarget(); currentTargetBearing = checkGpsNorth(isGpsNorth, currentTargetBearing); float previousCameraBearing = (float) currentCameraPosition.bearing; float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); - animatorMap.put(ANIMATOR_CAMERA_GPS_BEARING, new CameraGpsBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); - } - - private void cancelCameraCompassAnimations() { - cancelAnimator(PluginAnimator.ANIMATOR_CAMERA_COMPASS_BEARING); + createNewAnimator(ANIMATOR_CAMERA_GPS_BEARING, + new CameraGpsBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); } private void resetCameraCompassAnimation(CameraPosition currentCameraPosition) { - CameraLatLngAnimator cameraLatLngAnimator = (CameraLatLngAnimator) animatorMap.get(ANIMATOR_CAMERA_LATLNG); - CameraCompassBearingAnimator cameraCompassBearingAnimator = (CameraCompassBearingAnimator) animatorMap.get(ANIMATOR_CAMERA_COMPASS_BEARING); - if (cameraCompassBearingAnimator == null || cameraLatLngAnimator == null) { + CameraCompassBearingAnimator animator = + (CameraCompassBearingAnimator) animatorMap.get(ANIMATOR_CAMERA_COMPASS_BEARING); + if (animator == null) { return; } - cancelCameraCompassAnimations(); - float currentTargetBearing = cameraCompassBearingAnimator.getTarget(); + + float currentTargetBearing = animator.getTarget(); float previousCameraBearing = (float) currentCameraPosition.bearing; float normalizedCameraBearing = Utils.shortestRotation(currentTargetBearing, previousCameraBearing); - animatorMap.put(ANIMATOR_CAMERA_COMPASS_BEARING, new CameraCompassBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); + createNewAnimator(ANIMATOR_CAMERA_COMPASS_BEARING, + new CameraCompassBearingAnimator(previousCameraBearing, normalizedCameraBearing, cameraListeners)); + } + + private void createNewAnimator(@PluginAnimator.Type int animatorType, PluginAnimator animator) { + cancelAnimator(animatorType); + animatorMap.put(animatorType, animator); + } + + void cancelAllAnimations() { + for (@PluginAnimator.Type int animatorType : animatorMap.keySet()) { + cancelAnimator(animatorType); + } } private void cancelAnimator(@PluginAnimator.Type int animatorType) { @@ -352,6 +320,7 @@ private void cancelAnimator(@PluginAnimator.Type int animatorType) { if (animator != null) { animator.cancel(); animator.removeAllUpdateListeners(); + animatorMap.put(animatorType, null); } } } From 5b1dccc481bf51023b2dc10fd18a21e2c4d5e6a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 12 Jul 2018 16:52:18 +0200 Subject: [PATCH 05/10] [LLP] - zoom animator --- .../locationlayer/LocationLayerCamera.java | 10 +++ .../locationlayer/LocationLayerConstants.java | 2 + .../locationlayer/LocationLayerPlugin.java | 65 +++++++++++++++++++ .../MapboxCameraAnimatorAdapter.java | 38 +++++++++++ .../plugins/locationlayer/PluginAnimator.java | 6 +- .../PluginAnimatorCoordinator.java | 27 ++++++++ .../plugins/locationlayer/ZoomAnimator.java | 29 +++++++++ 7 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/MapboxCameraAnimatorAdapter.java create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/ZoomAnimator.java diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java index 819d1aa60..8853b927c 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java @@ -72,6 +72,11 @@ private void setLatLng(LatLng latLng) { onCameraMoveInvalidateListener.onInvalidateCameraMove(); } + private void setZoom(float zoom) { + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(zoom)); + onCameraMoveInvalidateListener.onInvalidateCameraMove(); + } + @Override public void onNewLatLngValue(LatLng latLng) { if (cameraMode == CameraMode.TRACKING @@ -108,6 +113,11 @@ public void onNewCompassBearingValue(float compassBearing) { } } + @Override + public void onNewZoomValue(float zoom) { + setZoom(zoom); + } + private void adjustGesturesThresholds() { if (isLocationTracking()) { adjustFocalPoint = true; diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java index 8c27ce027..814320f58 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java @@ -19,6 +19,8 @@ final class LocationLayerConstants { // Sets the duration of change of accuracy radius when a different value is provided. static final long ACCURACY_RADIUS_ANIMATION_DURATION = 250; + static final long DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION = 750; + // Sources static final String LOCATION_SOURCE = "mapbox-location-source"; static final String PROPERTY_GPS_BEARING = "mapbox-property-gps-bearing"; diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index d82705061..6b721b742 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -16,6 +16,7 @@ import com.mapbox.android.core.location.LocationEnginePriority; import com.mapbox.android.core.location.LocationEngineProvider; import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapView.OnMapChangedListener; @@ -28,8 +29,11 @@ import java.util.concurrent.CopyOnWriteArrayList; +import timber.log.Timber; + import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION; /** * The Location layer plugin provides location awareness to your mobile application. Enabling this @@ -303,6 +307,66 @@ public void applyStyle(LocationLayerOptions options) { updateMapWithOptions(options); } + /** + * Zooms to the desired zoom level. + * This API can only be used in pair with camera modes other than {@link CameraMode#NONE}. + * If you are not using any of {@link CameraMode} modes, + * use one of {@link MapboxMap#moveCamera(CameraUpdate)}, + * {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead. + * + * @param zoomLevel The desired zoom level. + * @param animationDuration The zoom animation duration. + * @param callback The callback with finish/cancel information + */ + public void zoomWhileTracking(double zoomLevel, long animationDuration, + @Nullable MapboxMap.CancelableCallback callback) { + if (!isLocationLayerStarted) { + return; + } else if (getCameraMode() == CameraMode.NONE) { + Timber.e("%s%s", + "LocationLayerPlugin#zoomWhileTracking method can only be used", + " when a camera mode other than CameraMode#NONE is engaged."); + return; + } + pluginAnimatorCoordinator.feedNewZoomLevel(zoomLevel, mapboxMap.getCameraPosition(), animationDuration, callback); + } + + /** + * Zooms to the desired zoom level. + * This API can only be used in pair with camera modes other than {@link CameraMode#NONE}. + * If you are not using any of {@link CameraMode} modes, + * use one of {@link MapboxMap#moveCamera(CameraUpdate)}, + * {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead. + * + * @param zoomLevel The desired zoom level. + * @param animationDuration The zoom animation duration. + */ + public void zoomWhileTracking(double zoomLevel, long animationDuration) { + zoomWhileTracking(zoomLevel, animationDuration, null); + } + + /** + * Zooms to the desired zoom level. + * This API can only be used in pair with camera modes other than {@link CameraMode#NONE}. + * If you are not using any of {@link CameraMode} modes, + * use one of {@link MapboxMap#moveCamera(CameraUpdate)}, + * {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead. + * + * @param zoomLevel The desired zoom level. + */ + public void zoomWhileTracking(double zoomLevel) { + zoomWhileTracking(zoomLevel, DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION, null); + } + + public void cancelZoomWhileTrackingAnimation() { + pluginAnimatorCoordinator.cancelZoomAnimation(); + } + + // TODO: 12/07/2018 docs + public void tiltTo(double tilt) { + + } + /** * Use to either force a location update or to manually control when the user location gets * updated. @@ -771,6 +835,7 @@ public void onCameraTrackingDismissed() { @Override public void onCameraTrackingChanged(int currentMode) { + pluginAnimatorCoordinator.cancelZoomAnimation(); for (OnCameraTrackingChangedListener listener : onCameraTrackingChangedListeners) { listener.onCameraTrackingChanged(currentMode); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/MapboxCameraAnimatorAdapter.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/MapboxCameraAnimatorAdapter.java new file mode 100644 index 000000000..d2381cc1e --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/MapboxCameraAnimatorAdapter.java @@ -0,0 +1,38 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.support.annotation.Nullable; + +import com.mapbox.mapboxsdk.maps.MapboxMap; + +import java.util.List; + +abstract class MapboxCameraAnimatorAdapter extends + PluginFloatAnimator { + private final MapboxMap.CancelableCallback cancelableCallback; + + MapboxCameraAnimatorAdapter(Float previous, Float target, + List updateListeners, + @Nullable MapboxMap.CancelableCallback cancelableCallback) { + super(previous, target, updateListeners); + this.cancelableCallback = cancelableCallback; + addListener(new MapboxAnimatorListener()); + } + + private final class MapboxAnimatorListener extends AnimatorListenerAdapter { + @Override + public void onAnimationCancel(Animator animation) { + if (cancelableCallback != null) { + cancelableCallback.onCancel(); + } + } + + @Override + public void onAnimationEnd(Animator animation) { + if (cancelableCallback != null) { + cancelableCallback.onFinish(); + } + } + } +} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java index db229436a..7dc40b5aa 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java @@ -25,7 +25,8 @@ abstract class PluginAnimator extends ValueAnimator implements ValueAnimat ANIMATOR_LAYER_COMPASS_BEARING, ANIMATOR_CAMERA_GPS_BEARING, ANIMATOR_CAMERA_COMPASS_BEARING, - ANIMATOR_LAYER_ACCURACY + ANIMATOR_LAYER_ACCURACY, + ANIMATOR_ZOOM }) @interface Type { } @@ -37,6 +38,7 @@ abstract class PluginAnimator extends ValueAnimator implements ValueAnimat static final int ANIMATOR_CAMERA_GPS_BEARING = 4; static final int ANIMATOR_CAMERA_COMPASS_BEARING = 5; static final int ANIMATOR_LAYER_ACCURACY = 6; + static final int ANIMATOR_ZOOM = 7; private final int animatorType = provideAnimatorType(); final List updateListeners; @@ -80,5 +82,7 @@ interface OnCameraAnimationsValuesChangeListener { void onNewGpsBearingValue(float gpsBearing); void onNewCompassBearingValue(float compassBearing); + + void onNewZoomValue(float zoom); } } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java index 1c85ec6fa..72816333a 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java @@ -6,10 +6,12 @@ import android.location.Location; import android.os.SystemClock; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.view.animation.LinearInterpolator; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapboxMap; import java.util.ArrayList; import java.util.HashMap; @@ -27,6 +29,7 @@ import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_COMPASS_BEARING; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_GPS_BEARING; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_LATLNG; +import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_ZOOM; final class PluginAnimatorCoordinator { @@ -108,6 +111,13 @@ void feedNewAccuracyRadius(float targetAccuracyRadius, boolean noAnimation) { this.previousAccuracyRadius = targetAccuracyRadius; } + // TODO: 12/07/2018 canceling zoom and tilt + void feedNewZoomLevel(double targetZoomLevel, @NonNull CameraPosition currentCameraPosition, long animationDuration, + @Nullable MapboxMap.CancelableCallback callback) { + updateZoomAnimator((float) targetZoomLevel, (float) currentCameraPosition.zoom, callback); + playZoomAnimator(animationDuration); + } + private LatLng getPreviousLayerLatLng() { LatLng previousLatLng; PluginAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); @@ -189,6 +199,12 @@ private void updateAccuracyAnimators(float targetAccuracyRadius, float previousA new LayerAccuracyAnimator(previousAccuracyRadius, targetAccuracyRadius, layerListeners)); } + private void updateZoomAnimator(float targetZoomLevel, float previousZoomLevel, + @Nullable MapboxMap.CancelableCallback cancelableCallback) { + createNewAnimator(ANIMATOR_ZOOM, + new ZoomAnimator(previousZoomLevel, targetZoomLevel, cameraListeners, cancelableCallback)); + } + private long getAnimationDuration() { long previousUpdateTimeStamp = locationUpdateTimestamp; locationUpdateTimestamp = SystemClock.elapsedRealtime(); @@ -242,6 +258,12 @@ private void playAccuracyAnimator(long duration) { animator.start(); } + private void playZoomAnimator(long duration) { + PluginAnimator animator = animatorMap.get(ANIMATOR_ZOOM); + animator.setDuration(duration); + animator.start(); + } + private void playCameraLocationAnimators(long duration) { List locationAnimators = new ArrayList<>(); locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_LATLNG)); @@ -309,6 +331,10 @@ private void createNewAnimator(@PluginAnimator.Type int animatorType, PluginAnim animatorMap.put(animatorType, animator); } + void cancelZoomAnimation() { + cancelAnimator(ANIMATOR_ZOOM); + } + void cancelAllAnimations() { for (@PluginAnimator.Type int animatorType : animatorMap.keySet()) { cancelAnimator(animatorType); @@ -320,6 +346,7 @@ private void cancelAnimator(@PluginAnimator.Type int animatorType) { if (animator != null) { animator.cancel(); animator.removeAllUpdateListeners(); + animator.removeAllListeners(); animatorMap.put(animatorType, null); } } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/ZoomAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/ZoomAnimator.java new file mode 100644 index 000000000..a1b1d4bf8 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/ZoomAnimator.java @@ -0,0 +1,29 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; +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 updateListeners, + @Nullable MapboxMap.CancelableCallback cancelableCallback) { + super(previous, target, updateListeners, cancelableCallback); + } + + @Override + int provideAnimatorType() { + return ANIMATOR_ZOOM; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (OnCameraAnimationsValuesChangeListener listener : updateListeners) { + listener.onNewZoomValue((Float) animation.getAnimatedValue()); + } + } + +} From ff8872cddb5fb537cbfe131be82ca290decff098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 16 Jul 2018 12:58:58 +0200 Subject: [PATCH 06/10] [LLP] - when modes are switched quickly in succession wrong focal point does not persist anymore --- .../locationlayer/LocationLayerPluginTest.kt | 17 +++++++++++++++++ .../locationlayer/LocationLayerCamera.java | 14 ++++++-------- .../plugins/locationlayer/modes/CameraMode.java | 3 +-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt index d036e6ad6..8631e1bb4 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -748,6 +748,23 @@ class LocationLayerPluginTest { executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) } + @Test + fun animators_focalPointAdjustment() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.cameraMode = CameraMode.NONE + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + assertThat(mapboxMap.uiSettings.focalPoint, nullValue()) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + @After fun afterTest() { Timber.e("@After: unregister idle resource") diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java index 8853b927c..6188d7447 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java @@ -84,12 +84,12 @@ public void onNewLatLngValue(LatLng latLng) { || cameraMode == CameraMode.TRACKING_GPS || cameraMode == CameraMode.TRACKING_GPS_NORTH) { setLatLng(latLng); - } - if (adjustFocalPoint) { - PointF focalPoint = mapboxMap.getProjection().toScreenLocation(latLng); - mapboxMap.getUiSettings().setFocalPoint(focalPoint); - adjustFocalPoint = false; + if (adjustFocalPoint) { + PointF focalPoint = mapboxMap.getProjection().toScreenLocation(latLng); + mapboxMap.getUiSettings().setFocalPoint(focalPoint); + adjustFocalPoint = false; + } } } @@ -170,9 +170,7 @@ public void onMove(MoveGestureDetector detector) { return; } - if (isLocationTracking()) { - setCameraMode(CameraMode.NONE); - } + setCameraMode(CameraMode.NONE); } @Override diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java index 68692a429..59cff613e 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java @@ -35,7 +35,7 @@ private CameraMode() { * * @since 0.5.0 */ - public static final int NONE = 0x00000000; + public static final int NONE = 0x00000008; /** * Camera does not track location, but does track compass bearing. @@ -74,7 +74,6 @@ private CameraMode() { */ public static final int TRACKING_GPS = 0x00000022; - /** * Camera tracks the user location, with bearing * always set to north (0). From f88e3a367415f599f27fd9f9ab729733d851ddf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 16 Jul 2018 13:23:44 +0200 Subject: [PATCH 07/10] [LLP] - zoom animator tests --- .../locationlayer/LocationLayerPluginTest.kt | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt index 8631e1bb4..df1c0b5b2 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -765,6 +765,57 @@ class LocationLayerPluginTest { executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) } + @Test + fun animators_dontZoomWhileNotTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.NONE + val zoom = mapboxMap.cameraPosition.zoom + plugin.zoomWhileTracking(10.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) + + assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + + @Test + fun animators_zoomWhileTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.zoomWhileTracking(10.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) + + assertEquals(10.0, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + + @Test + fun animators_zoomWhileTrackingCanceledOnModeChange() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.zoomWhileTracking(15.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + plugin.cameraMode = CameraMode.NONE + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + + assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + @After fun afterTest() { Timber.e("@After: unregister idle resource") From ba68173e2a3b104f68213a28b1df57596cede8c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 16 Jul 2018 14:23:01 +0200 Subject: [PATCH 08/10] [LLP] - tilt animator --- .../locationlayer/LocationLayerPluginTest.kt | 137 ++++++++++++++++++ .../location/LocationLayerModesActivity.java | 16 ++ .../locationlayer/LocationLayerCamera.java | 10 ++ .../locationlayer/LocationLayerConstants.java | 4 + .../locationlayer/LocationLayerPlugin.java | 62 +++++++- .../plugins/locationlayer/PluginAnimator.java | 6 +- .../PluginAnimatorCoordinator.java | 23 +++ .../plugins/locationlayer/TiltAnimator.java | 27 ++++ 8 files changed, 282 insertions(+), 3 deletions(-) create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/TiltAnimator.java diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt index df1c0b5b2..301d92dd9 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -816,6 +816,143 @@ class LocationLayerPluginTest { executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) } + @Test + fun animators_dontZoomWhileStopped() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + plugin.cameraMode = CameraMode.TRACKING + val zoom = mapboxMap.cameraPosition.zoom + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + plugin.zoomWhileTracking(10.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION) + + assertEquals(zoom, mapboxMap.cameraPosition.zoom, 0.1) + } + } + + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, null, false)) + } + + @Test + fun animators_cancelZoomWhileTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.zoomWhileTracking(15.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + plugin.cancelZoomWhileTrackingAnimation() + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION / 2) + + assertEquals(15.0 / 2.0, mapboxMap.cameraPosition.zoom, 3.0) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + + @Test + fun animators_dontTiltWhileNotTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.NONE + val tilt = mapboxMap.cameraPosition.tilt + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) + + assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + + @Test + fun animators_tiltWhileTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) + + assertEquals(30.0, mapboxMap.cameraPosition.tilt, 0.1) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + + @Test + fun animators_tiltWhileTrackingCanceledOnModeChange() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + plugin.cameraMode = CameraMode.NONE + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + + assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + + @Test + fun animators_dontTiltWhileStopped() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + + val testLifecycleOwner = TestLifecycleOwner() + testLifecycleOwner.markState(Lifecycle.State.RESUMED) + testLifecycleOwner.lifecycle.addObserver(plugin) + + plugin.cameraMode = CameraMode.TRACKING + val tilt = mapboxMap.cameraPosition.tilt + + testLifecycleOwner.markState(Lifecycle.State.CREATED) + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION) + + assertEquals(tilt, mapboxMap.cameraPosition.tilt, 0.1) + } + } + + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, null, false)) + } + + @Test + fun animators_cancelTiltWhileTracking() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.cameraMode = CameraMode.TRACKING + plugin.tiltWhileTracking(30.0) + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + plugin.cancelTiltWhileTrackingAnimation() + uiController.loopMainThreadForAtLeast(DEFAULT_TRACKING_TILT_ANIMATION_DURATION / 2) + + assertEquals(30.0 / 2.0, mapboxMap.cameraPosition.tilt, 3.0) + } + } + + executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity)) + } + @After fun afterTest() { Timber.e("@After: unregister idle resource") diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java index 361253a8d..5edbcf03e 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java @@ -316,6 +316,22 @@ private void showTrackingListDialog() { locationLayerPlugin.setCameraMode(CameraMode.TRACKING_GPS_NORTH); } listPopup.dismiss(); + + if (locationLayerPlugin.getCameraMode() != CameraMode.NONE) { + locationLayerPlugin.zoomWhileTracking(15, 750, new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + // No impl + } + + @Override + public void onFinish() { + locationLayerPlugin.tiltWhileTracking(45); + } + }); + } else { + mapboxMap.easeCamera(CameraUpdateFactory.tiltTo(0)); + } }); listPopup.show(); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java index 6188d7447..2aad8dfc8 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java @@ -77,6 +77,11 @@ private void setZoom(float zoom) { onCameraMoveInvalidateListener.onInvalidateCameraMove(); } + private void setTilt(float tilt) { + mapboxMap.moveCamera(CameraUpdateFactory.tiltTo(tilt)); + onCameraMoveInvalidateListener.onInvalidateCameraMove(); + } + @Override public void onNewLatLngValue(LatLng latLng) { if (cameraMode == CameraMode.TRACKING @@ -118,6 +123,11 @@ public void onNewZoomValue(float zoom) { setZoom(zoom); } + @Override + public void onNewTiltValue(float tilt) { + setTilt(tilt); + } + private void adjustGesturesThresholds() { if (isLocationTracking()) { adjustFocalPoint = true; diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java index 814320f58..7cf1b43a9 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java @@ -19,8 +19,12 @@ final class LocationLayerConstants { // Sets the duration of change of accuracy radius when a different value is provided. static final long ACCURACY_RADIUS_ANIMATION_DURATION = 250; + // Default animation duration for zooming while tracking. static final long DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION = 750; + // Default animation duration for tilting while tracking. + static final long DEFAULT_TRACKING_TILT_ANIMATION_DURATION = 1250; + // Sources static final String LOCATION_SOURCE = "mapbox-location-source"; static final String PROPERTY_GPS_BEARING = "mapbox-property-gps-bearing"; diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index 6b721b742..2cf811d9c 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -33,6 +33,7 @@ import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.DEFAULT_TRACKING_TILT_ANIMATION_DURATION; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION; /** @@ -358,13 +359,69 @@ public void zoomWhileTracking(double zoomLevel) { zoomWhileTracking(zoomLevel, DEFAULT_TRACKING_ZOOM_ANIMATION_DURATION, null); } + /** + * Cancels animation started by {@link #zoomWhileTracking(double, long, MapboxMap.CancelableCallback)}. + */ public void cancelZoomWhileTrackingAnimation() { pluginAnimatorCoordinator.cancelZoomAnimation(); } - // TODO: 12/07/2018 docs - public void tiltTo(double tilt) { + /** + * Tilts the camera. + * This API can only be used in pair with camera modes other than {@link CameraMode#NONE}. + * If you are not using any of {@link CameraMode} modes, + * use one of {@link MapboxMap#moveCamera(CameraUpdate)}, + * {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead. + * + * @param tilt The desired camera tilt. + * @param animationDuration The tilt animation duration. + * @param callback The callback with finish/cancel information + */ + public void tiltWhileTracking(double tilt, long animationDuration, + @Nullable MapboxMap.CancelableCallback callback) { + if (!isLocationLayerStarted) { + return; + } else if (getCameraMode() == CameraMode.NONE) { + Timber.e("%s%s", + "LocationLayerPlugin#tiltWhileTracking method can only be used", + " when a camera mode other than CameraMode#NONE is engaged."); + return; + } + pluginAnimatorCoordinator.feedNewTilt(tilt, mapboxMap.getCameraPosition(), animationDuration, callback); + } + /** + * Tilts the camera. + * This API can only be used in pair with camera modes other than {@link CameraMode#NONE}. + * If you are not using any of {@link CameraMode} modes, + * use one of {@link MapboxMap#moveCamera(CameraUpdate)}, + * {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead. + * + * @param tilt The desired camera tilt. + * @param animationDuration The tilt animation duration. + */ + public void tiltWhileTracking(double tilt, long animationDuration) { + tiltWhileTracking(tilt, animationDuration, null); + } + + /** + * Tilts the camera. + * This API can only be used in pair with camera modes other than {@link CameraMode#NONE}. + * If you are not using any of {@link CameraMode} modes, + * use one of {@link MapboxMap#moveCamera(CameraUpdate)}, + * {@link MapboxMap#easeCamera(CameraUpdate)} or {@link MapboxMap#animateCamera(CameraUpdate)} instead. + * + * @param tilt The desired camera tilt. + */ + public void tiltWhileTracking(double tilt) { + tiltWhileTracking(tilt, DEFAULT_TRACKING_TILT_ANIMATION_DURATION, null); + } + + /** + * Cancels animation started by {@link #tiltWhileTracking(double, long, MapboxMap.CancelableCallback)}. + */ + public void cancelTiltWhileTrackingAnimation() { + pluginAnimatorCoordinator.cancelTiltAnimation(); } /** @@ -836,6 +893,7 @@ public void onCameraTrackingDismissed() { @Override public void onCameraTrackingChanged(int currentMode) { pluginAnimatorCoordinator.cancelZoomAnimation(); + pluginAnimatorCoordinator.cancelTiltAnimation(); for (OnCameraTrackingChangedListener listener : onCameraTrackingChangedListeners) { listener.onCameraTrackingChanged(currentMode); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java index 7dc40b5aa..faa2a1ae4 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimator.java @@ -26,7 +26,8 @@ abstract class PluginAnimator extends ValueAnimator implements ValueAnimat ANIMATOR_CAMERA_GPS_BEARING, ANIMATOR_CAMERA_COMPASS_BEARING, ANIMATOR_LAYER_ACCURACY, - ANIMATOR_ZOOM + ANIMATOR_ZOOM, + ANIMATOR_TILT }) @interface Type { } @@ -39,6 +40,7 @@ abstract class PluginAnimator extends ValueAnimator implements ValueAnimat static final int ANIMATOR_CAMERA_COMPASS_BEARING = 5; static final int ANIMATOR_LAYER_ACCURACY = 6; static final int ANIMATOR_ZOOM = 7; + static final int ANIMATOR_TILT = 8; private final int animatorType = provideAnimatorType(); final List updateListeners; @@ -84,5 +86,7 @@ interface OnCameraAnimationsValuesChangeListener { void onNewCompassBearingValue(float compassBearing); void onNewZoomValue(float zoom); + + void onNewTiltValue(float tilt); } } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java index 72816333a..7a87a14fd 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java @@ -29,6 +29,7 @@ import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_COMPASS_BEARING; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_GPS_BEARING; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_LAYER_LATLNG; +import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_TILT; import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_ZOOM; final class PluginAnimatorCoordinator { @@ -118,6 +119,12 @@ void feedNewZoomLevel(double targetZoomLevel, @NonNull CameraPosition currentCam playZoomAnimator(animationDuration); } + void feedNewTilt(double targetTilt, @NonNull CameraPosition currentCameraPosition, long animationDuration, + @Nullable MapboxMap.CancelableCallback callback) { + updateTiltAnimator((float) targetTilt, (float) currentCameraPosition.tilt, callback); + playTiltAnimator(animationDuration); + } + private LatLng getPreviousLayerLatLng() { LatLng previousLatLng; PluginAnimator latLngAnimator = animatorMap.get(ANIMATOR_LAYER_LATLNG); @@ -205,6 +212,12 @@ private void updateZoomAnimator(float targetZoomLevel, float previousZoomLevel, new ZoomAnimator(previousZoomLevel, targetZoomLevel, cameraListeners, cancelableCallback)); } + private void updateTiltAnimator(float targetTilt, float previousTiltLevel, + @Nullable MapboxMap.CancelableCallback cancelableCallback) { + createNewAnimator(ANIMATOR_TILT, + new TiltAnimator(previousTiltLevel, targetTilt, cameraListeners, cancelableCallback)); + } + private long getAnimationDuration() { long previousUpdateTimeStamp = locationUpdateTimestamp; locationUpdateTimestamp = SystemClock.elapsedRealtime(); @@ -264,6 +277,12 @@ private void playZoomAnimator(long duration) { animator.start(); } + private void playTiltAnimator(long duration) { + PluginAnimator animator = animatorMap.get(ANIMATOR_TILT); + animator.setDuration(duration); + animator.start(); + } + private void playCameraLocationAnimators(long duration) { List locationAnimators = new ArrayList<>(); locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_LATLNG)); @@ -335,6 +354,10 @@ void cancelZoomAnimation() { cancelAnimator(ANIMATOR_ZOOM); } + void cancelTiltAnimation() { + cancelAnimator(ANIMATOR_TILT); + } + void cancelAllAnimations() { for (@PluginAnimator.Type int animatorType : animatorMap.keySet()) { cancelAnimator(animatorType); diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/TiltAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/TiltAnimator.java new file mode 100644 index 000000000..2a12622df --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/TiltAnimator.java @@ -0,0 +1,27 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; +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 updateListeners, + @Nullable MapboxMap.CancelableCallback cancelableCallback) { + super(previous, target, updateListeners, cancelableCallback); + } + + @Override + int provideAnimatorType() { + return ANIMATOR_TILT; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + for (OnCameraAnimationsValuesChangeListener listener : updateListeners) { + listener.onNewTiltValue((Float) animation.getAnimatedValue()); + } + } +} From a6b0f3fcc06f83e29199c8fbed8e75748ef96675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 16 Jul 2018 15:07:29 +0200 Subject: [PATCH 09/10] [LLP] - ignoring animation duration based tests as animations are disabled on test devices --- .../plugins/locationlayer/LocationLayerPluginTest.kt | 12 ++++++++---- .../locationlayer/PluginAnimatorCoordinator.java | 1 - 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt index 301d92dd9..4b54639c4 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -18,6 +18,7 @@ import android.support.test.rule.GrantPermissionRule import android.support.test.runner.AndroidJUnit4 import android.support.v4.content.ContextCompat import com.mapbox.geojson.Point +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.constants.Style import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.MapboxMap @@ -34,12 +35,9 @@ import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_REN import com.mapbox.mapboxsdk.style.layers.PropertyFactory import com.mapbox.mapboxsdk.style.sources.GeoJsonSource import org.hamcrest.CoreMatchers.* -import org.junit.After +import org.junit.* import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals -import org.junit.Before -import org.junit.Rule -import org.junit.Test import org.junit.runner.RunWith import timber.log.Timber @@ -799,6 +797,7 @@ class LocationLayerPluginTest { } @Test + @Ignore fun animators_zoomWhileTrackingCanceledOnModeChange() { val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, @@ -827,6 +826,8 @@ class LocationLayerPluginTest { testLifecycleOwner.lifecycle.addObserver(plugin) plugin.cameraMode = CameraMode.TRACKING + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(5.0)) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) val zoom = mapboxMap.cameraPosition.zoom testLifecycleOwner.markState(Lifecycle.State.CREATED) @@ -842,6 +843,7 @@ class LocationLayerPluginTest { } @Test + @Ignore fun animators_cancelZoomWhileTracking() { val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, @@ -893,6 +895,7 @@ class LocationLayerPluginTest { } @Test + @Ignore fun animators_tiltWhileTrackingCanceledOnModeChange() { val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, @@ -936,6 +939,7 @@ class LocationLayerPluginTest { } @Test + @Ignore fun animators_cancelTiltWhileTracking() { val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java index 7a87a14fd..611a7b76b 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java @@ -112,7 +112,6 @@ void feedNewAccuracyRadius(float targetAccuracyRadius, boolean noAnimation) { this.previousAccuracyRadius = targetAccuracyRadius; } - // TODO: 12/07/2018 canceling zoom and tilt void feedNewZoomLevel(double targetZoomLevel, @NonNull CameraPosition currentCameraPosition, long animationDuration, @Nullable MapboxMap.CancelableCallback callback) { updateZoomAnimator((float) targetZoomLevel, (float) currentCameraPosition.zoom, callback); From e69206fd5857bec1eb7d0698f7d2952113786cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 18 Jul 2018 14:48:42 +0200 Subject: [PATCH 10/10] [LLP] - master chagelog entry for new camera zoom in/out and tilt methods --- plugin-locationlayer/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugin-locationlayer/CHANGELOG.md b/plugin-locationlayer/CHANGELOG.md index 62f46ef3f..e9bba0801 100644 --- a/plugin-locationlayer/CHANGELOG.md +++ b/plugin-locationlayer/CHANGELOG.md @@ -2,6 +2,9 @@ Mapbox welcomes participation and contributions from everyone. +### master +- Additional methods to tilt and zoom in/out the camera while camera tracking is engaged [#583](https://github.com/mapbox/mapbox-plugins-android/pull/583) + ### 0.6.0 - July 9, 2018 - Animate accuracy ring when new value is provided [#577](https://github.com/mapbox/mapbox-plugins-android/pull/577) - Allow pre-loaded MapboxMap images / maki icons in LocationLayerOptions [#574](https://github.com/mapbox/mapbox-plugins-android/pull/574)