make sure to hard-cancel all ignored location animators
This commit is contained in:
@@ -74,6 +74,16 @@ final class LocationAnimatorCoordinator {
|
||||
for (AnimatorListenerHolder holder : listenerHolders) {
|
||||
listeners.append(holder.getAnimatorType(), holder.getListener());
|
||||
}
|
||||
|
||||
for (int i = 0; i < animatorArray.size(); i++) {
|
||||
@MapboxAnimator.Type int animatorType = animatorArray.keyAt(i);
|
||||
if (listeners.get(animatorType) == null) {
|
||||
MapboxAnimator animator = animatorArray.get(animatorType);
|
||||
if (animator != null) {
|
||||
animator.makeInvalid();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void feedNewLocation(@NonNull Location newLocation, @NonNull CameraPosition currentCameraPosition,
|
||||
@@ -397,6 +407,8 @@ final class LocationAnimatorCoordinator {
|
||||
MapboxFloatAnimator gpsBearingAnimator = (MapboxFloatAnimator) animatorArray.get(ANIMATOR_LAYER_GPS_BEARING);
|
||||
MapboxFloatAnimator compassBearingAnimator =
|
||||
(MapboxFloatAnimator) animatorArray.get(ANIMATOR_LAYER_COMPASS_BEARING);
|
||||
MapboxFloatAnimator accuracyAnimator =
|
||||
(MapboxFloatAnimator) animatorArray.get(ANIMATOR_LAYER_ACCURACY);
|
||||
|
||||
if (latLngAnimator != null && gpsBearingAnimator != null) {
|
||||
LatLng currentLatLng = (LatLng) latLngAnimator.getAnimatedValue();
|
||||
@@ -420,6 +432,10 @@ final class LocationAnimatorCoordinator {
|
||||
compassAnimationEnabled ? COMPASS_UPDATE_RATE_MS : 0,
|
||||
ANIMATOR_LAYER_COMPASS_BEARING);
|
||||
}
|
||||
|
||||
if (accuracyAnimator != null) {
|
||||
feedNewAccuracyRadius(previousAccuracyRadius, false);
|
||||
}
|
||||
}
|
||||
|
||||
void cancelZoomAnimation() {
|
||||
|
||||
@@ -50,6 +50,13 @@ abstract class MapboxAnimator<K> extends ValueAnimator implements ValueAnimator.
|
||||
private final double minUpdateInterval;
|
||||
private long timeElapsed;
|
||||
|
||||
/**
|
||||
* Makes this animator invalid and prevents it from pushing any more updates to the listener.
|
||||
*
|
||||
* This can be used to prevent propagating final updates when the animator should be immediately canceled.
|
||||
*/
|
||||
private boolean invalid;
|
||||
|
||||
MapboxAnimator(@NonNull @Size(min = 2) K[] values, @NonNull AnimationsValueChangeListener<K> updateListener,
|
||||
int maxAnimationFps) {
|
||||
minUpdateInterval = 1E9 / maxAnimationFps;
|
||||
@@ -82,7 +89,9 @@ abstract class MapboxAnimator<K> extends ValueAnimator implements ValueAnimator.
|
||||
}
|
||||
|
||||
private void postUpdates() {
|
||||
updateListener.onNewAnimationValue(animatedValue);
|
||||
if (!invalid) {
|
||||
updateListener.onNewAnimationValue(animatedValue);
|
||||
}
|
||||
}
|
||||
|
||||
K getTarget() {
|
||||
@@ -94,4 +103,8 @@ abstract class MapboxAnimator<K> extends ValueAnimator implements ValueAnimator.
|
||||
interface AnimationsValueChangeListener<K> {
|
||||
void onNewAnimationValue(K value);
|
||||
}
|
||||
|
||||
public void makeInvalid() {
|
||||
invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.mapbox.mapboxsdk.location
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.ValueAnimator
|
||||
import android.location.Location
|
||||
import android.util.SparseArray
|
||||
import android.view.animation.LinearInterpolator
|
||||
@@ -9,7 +10,6 @@ import com.mapbox.mapboxsdk.geometry.LatLng
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_TRACKING_TILT_ANIM_DURATION
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_TRACKING_ZOOM_ANIM_DURATION
|
||||
import com.mapbox.mapboxsdk.location.MapboxAnimator.*
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap
|
||||
import com.mapbox.mapboxsdk.maps.Projection
|
||||
@@ -517,16 +517,16 @@ class LocationAnimatorCoordinatorTest {
|
||||
@Test
|
||||
fun updateListeners() {
|
||||
val listener = Mockito.mock(AnimationsValueChangeListener::class.java)
|
||||
val holder = AnimatorListenerHolder(RenderMode.NORMAL, listener)
|
||||
val holder = AnimatorListenerHolder(ANIMATOR_LAYER_LATLNG, listener)
|
||||
val set = HashSet<AnimatorListenerHolder>().also {
|
||||
it.add(holder)
|
||||
}
|
||||
locationAnimatorCoordinator.updateAnimatorListenerHolders(set)
|
||||
|
||||
val listener2 = Mockito.mock(AnimationsValueChangeListener::class.java)
|
||||
val holder2 = AnimatorListenerHolder(RenderMode.NORMAL, listener2)
|
||||
val holder2 = AnimatorListenerHolder(ANIMATOR_LAYER_LATLNG, listener2)
|
||||
val listener3 = Mockito.mock(AnimationsValueChangeListener::class.java)
|
||||
val holder3 = AnimatorListenerHolder(CameraMode.TRACKING_GPS, listener3)
|
||||
val holder3 = AnimatorListenerHolder(ANIMATOR_LAYER_ACCURACY, listener3)
|
||||
val set2 = HashSet<AnimatorListenerHolder>().also {
|
||||
it.add(holder2)
|
||||
it.add(holder3)
|
||||
@@ -538,6 +538,37 @@ class LocationAnimatorCoordinatorTest {
|
||||
assertTrue(locationAnimatorCoordinator.listeners.contains(listener3))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateListeners_listenerRemoved_animtorInvalid() {
|
||||
// setup accuracy animator
|
||||
val listener: AnimationsValueChangeListener<Float> = mockk(relaxUnitFun = true)
|
||||
val holder = AnimatorListenerHolder(ANIMATOR_LAYER_ACCURACY, listener)
|
||||
val set = HashSet<AnimatorListenerHolder>().also {
|
||||
it.add(holder)
|
||||
}
|
||||
locationAnimatorCoordinator.updateAnimatorListenerHolders(set)
|
||||
locationAnimatorCoordinator.feedNewAccuracyRadius(500f, true)
|
||||
|
||||
// reset animator listeners which should make the previously created animator invalid
|
||||
val listener2: AnimationsValueChangeListener<*> = mockk()
|
||||
val holder2 = AnimatorListenerHolder(ANIMATOR_LAYER_LATLNG, listener2)
|
||||
val listener3: AnimationsValueChangeListener<*> = mockk()
|
||||
val holder3 = AnimatorListenerHolder(ANIMATOR_CAMERA_GPS_BEARING, listener3)
|
||||
val set2 = HashSet<AnimatorListenerHolder>().also {
|
||||
it.add(holder2)
|
||||
it.add(holder3)
|
||||
}
|
||||
locationAnimatorCoordinator.updateAnimatorListenerHolders(set2)
|
||||
|
||||
// try pushing an update to verify it was ignored
|
||||
val valueAnimator: ValueAnimator = mockk()
|
||||
every { valueAnimator.animatedValue } returns 10f
|
||||
val animator = locationAnimatorCoordinator.animatorArray.get(ANIMATOR_LAYER_ACCURACY)
|
||||
animator.onAnimationUpdate(valueAnimator)
|
||||
|
||||
verify(exactly = 0) { listener.onNewAnimationValue(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun feedNewCompassBearing_withAnimation() {
|
||||
locationAnimatorCoordinator.setCompassAnimationEnabled(true)
|
||||
|
||||
Reference in New Issue
Block a user