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