[android] reworked zoomIn and zoomOut to use ValueAnimators (#11382)
This commit is contained in:
@@ -218,15 +218,17 @@ final class MapGestureDetector {
|
||||
}
|
||||
|
||||
void cancelAnimators() {
|
||||
if (scaleAnimator != null) {
|
||||
scaleAnimator.cancel();
|
||||
}
|
||||
if (rotateAnimator != null) {
|
||||
rotateAnimator.cancel();
|
||||
}
|
||||
|
||||
animationsTimeoutHandler.removeCallbacksAndMessages(null);
|
||||
scheduledAnimators.clear();
|
||||
|
||||
cancelAnimator(scaleAnimator);
|
||||
cancelAnimator(rotateAnimator);
|
||||
}
|
||||
|
||||
private void cancelAnimator(Animator animator) {
|
||||
if (animator != null && animator.isStarted()) {
|
||||
animator.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -338,15 +340,18 @@ final class MapGestureDetector {
|
||||
transform.cancelTransitions();
|
||||
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);
|
||||
|
||||
PointF zoomFocalPoint;
|
||||
// Single finger double tap
|
||||
if (focalPoint != null) {
|
||||
// User provided focal point
|
||||
transform.zoomIn(focalPoint);
|
||||
zoomFocalPoint = focalPoint;
|
||||
} else {
|
||||
// Zoom in on gesture
|
||||
transform.zoomIn(new PointF(motionEvent.getX(), motionEvent.getY()));
|
||||
zoomFocalPoint = new PointF(motionEvent.getX(), motionEvent.getY());
|
||||
}
|
||||
|
||||
zoomInAnimated(zoomFocalPoint, false);
|
||||
|
||||
sendTelemetryEvent(Events.DOUBLE_TAP, new PointF(motionEvent.getX(), motionEvent.getY()));
|
||||
|
||||
return true;
|
||||
@@ -512,7 +517,7 @@ final class MapGestureDetector {
|
||||
double zoomAddition = calculateScale(velocityXY, detector.isScalingOut());
|
||||
double currentZoom = transform.getRawZoom();
|
||||
long animationTime = (long) (Math.abs(zoomAddition) * 1000 / 4);
|
||||
scaleAnimator = createScaleAnimator(currentZoom, zoomAddition, animationTime);
|
||||
scaleAnimator = createScaleAnimator(currentZoom, zoomAddition, scaleFocalPoint, animationTime);
|
||||
scheduleAnimator(scaleAnimator);
|
||||
}
|
||||
|
||||
@@ -540,39 +545,6 @@ final class MapGestureDetector {
|
||||
return zoomAddition;
|
||||
}
|
||||
|
||||
private Animator createScaleAnimator(double currentZoom, double zoomAddition, long animationTime) {
|
||||
ValueAnimator animator = ValueAnimator.ofFloat((float) currentZoom, (float) (currentZoom + zoomAddition));
|
||||
animator.setDuration(animationTime);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
transform.setZoom((Float) animation.getAnimatedValue(), scaleFocalPoint, 0);
|
||||
}
|
||||
});
|
||||
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
transform.cancelTransitions();
|
||||
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_ANIMATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
transform.cancelTransitions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
}
|
||||
});
|
||||
return animator;
|
||||
}
|
||||
|
||||
private double getNewZoom(float scaleFactor, boolean quickZoom) {
|
||||
double zoomBy = Math.log(scaleFactor) / Math.log(Math.PI / 2);
|
||||
if (quickZoom) {
|
||||
@@ -776,16 +748,95 @@ final class MapGestureDetector {
|
||||
transform.cancelTransitions();
|
||||
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_GESTURE);
|
||||
|
||||
PointF zoomFocalPoint;
|
||||
// Single finger double tap
|
||||
if (focalPoint != null) {
|
||||
transform.zoomOut(focalPoint);
|
||||
// User provided focal point
|
||||
zoomFocalPoint = focalPoint;
|
||||
} else {
|
||||
transform.zoomOut(detector.getFocalPoint());
|
||||
// Zoom in on gesture
|
||||
zoomFocalPoint = detector.getFocalPoint();
|
||||
}
|
||||
|
||||
zoomOutAnimated(zoomFocalPoint, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private Animator createScaleAnimator(double currentZoom, double zoomAddition, PointF animationFocalPoint,
|
||||
long animationTime) {
|
||||
ValueAnimator animator = ValueAnimator.ofFloat((float) currentZoom, (float) (currentZoom + zoomAddition));
|
||||
animator.setDuration(animationTime);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
transform.setZoom((Float) animation.getAnimatedValue(), animationFocalPoint);
|
||||
}
|
||||
});
|
||||
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
transform.cancelTransitions();
|
||||
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_ANIMATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
transform.cancelTransitions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
}
|
||||
});
|
||||
return animator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zoom in by 1.
|
||||
*
|
||||
* @param zoomFocalPoint focal point of zoom animation
|
||||
* @param runImmediately if true, animation will be started right away, otherwise it will wait until
|
||||
* {@link MotionEvent#ACTION_UP} is registered.
|
||||
*/
|
||||
void zoomInAnimated(PointF zoomFocalPoint, boolean runImmediately) {
|
||||
zoomAnimated(true, zoomFocalPoint, runImmediately);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zoom out by 1.
|
||||
*
|
||||
* @param zoomFocalPoint focal point of zoom animation
|
||||
* @param runImmediately if true, animation will be started right away, otherwise it will wait until
|
||||
* {@link MotionEvent#ACTION_UP} is registered.
|
||||
*/
|
||||
void zoomOutAnimated(PointF zoomFocalPoint, boolean runImmediately) {
|
||||
zoomAnimated(false, zoomFocalPoint, runImmediately);
|
||||
}
|
||||
|
||||
private void zoomAnimated(boolean zoomIn, PointF zoomFocalPoint, boolean runImmediately) {
|
||||
//canceling here as well, because when using a button it will not be canceled automatically by onDown()
|
||||
cancelAnimator(scaleAnimator);
|
||||
|
||||
double currentZoom = transform.getRawZoom();
|
||||
scaleAnimator = createScaleAnimator(
|
||||
currentZoom,
|
||||
zoomIn ? 1 : -1,
|
||||
zoomFocalPoint,
|
||||
MapboxConstants.ANIMATION_DURATION);
|
||||
if (runImmediately) {
|
||||
scaleAnimator.start();
|
||||
} else {
|
||||
scheduleAnimator(scaleAnimator);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendTelemetryEvent(String eventType, PointF focalPoint) {
|
||||
if (isZoomValid(transform)) {
|
||||
MapEventFactory mapEventFactory = new MapEventFactory();
|
||||
|
||||
@@ -21,12 +21,14 @@ final class MapKeyListener {
|
||||
|
||||
private final Transform transform;
|
||||
private final UiSettings uiSettings;
|
||||
private final MapGestureDetector mapGestureDetector;
|
||||
|
||||
private TrackballLongPressTimeOut currentTrackballLongPressTimeOut;
|
||||
|
||||
MapKeyListener(@NonNull Transform transform, @NonNull UiSettings uiSettings) {
|
||||
MapKeyListener(Transform transform, UiSettings uiSettings, MapGestureDetector mapGestureDetector) {
|
||||
this.transform = transform;
|
||||
this.uiSettings = uiSettings;
|
||||
this.mapGestureDetector = mapGestureDetector;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,7 +126,7 @@ final class MapKeyListener {
|
||||
|
||||
// Zoom out
|
||||
PointF focalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
|
||||
transform.zoomOut(focalPoint);
|
||||
mapGestureDetector.zoomOutAnimated(focalPoint, true);
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -160,7 +162,7 @@ final class MapKeyListener {
|
||||
|
||||
// Zoom in
|
||||
PointF focalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
|
||||
transform.zoomIn(focalPoint);
|
||||
mapGestureDetector.zoomInAnimated(focalPoint, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -215,7 +217,7 @@ final class MapKeyListener {
|
||||
if (currentTrackballLongPressTimeOut != null) {
|
||||
// Zoom in
|
||||
PointF focalPoint = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
|
||||
transform.zoomIn(focalPoint);
|
||||
mapGestureDetector.zoomInAnimated(focalPoint, true);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -257,7 +259,7 @@ final class MapKeyListener {
|
||||
if (!cancelled) {
|
||||
// Zoom out
|
||||
PointF pointF = new PointF(uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
|
||||
transform.zoomOut(pointF);
|
||||
mapGestureDetector.zoomOutAnimated(pointF, true);
|
||||
|
||||
// Ensure the up action is not run
|
||||
currentTrackballLongPressTimeOut = null;
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.mapbox.android.telemetry.Event;
|
||||
import com.mapbox.android.telemetry.MapEventFactory;
|
||||
import com.mapbox.android.telemetry.MapboxTelemetry;
|
||||
import com.mapbox.mapboxsdk.BuildConfig;
|
||||
|
||||
import com.mapbox.mapboxsdk.R;
|
||||
import com.mapbox.mapboxsdk.annotations.Annotation;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
|
||||
@@ -177,12 +176,12 @@ public class MapView extends FrameLayout {
|
||||
// user input
|
||||
mapGestureDetector = new MapGestureDetector(context, transform, proj, uiSettings,
|
||||
annotationManager, cameraChangeDispatcher);
|
||||
mapKeyListener = new MapKeyListener(transform, uiSettings);
|
||||
mapKeyListener = new MapKeyListener(transform, uiSettings, mapGestureDetector);
|
||||
|
||||
// overlain zoom buttons
|
||||
mapZoomButtonController = new MapZoomButtonController(new ZoomButtonsController(this));
|
||||
MapZoomControllerListener zoomListener = new MapZoomControllerListener(mapGestureDetector, uiSettings, transform,
|
||||
cameraChangeDispatcher, getWidth(), getHeight());
|
||||
MapZoomControllerListener zoomListener = new MapZoomControllerListener(
|
||||
mapGestureDetector, cameraChangeDispatcher, getWidth(), getHeight());
|
||||
mapZoomButtonController.bind(uiSettings, zoomListener);
|
||||
|
||||
compassView.injectCompassAnimationListener(createCompassAnimationListener(cameraChangeDispatcher));
|
||||
@@ -1030,17 +1029,13 @@ public class MapView extends FrameLayout {
|
||||
private static class MapZoomControllerListener implements ZoomButtonsController.OnZoomListener {
|
||||
|
||||
private final MapGestureDetector mapGestureDetector;
|
||||
private final UiSettings uiSettings;
|
||||
private final Transform transform;
|
||||
private final CameraChangeDispatcher cameraChangeDispatcher;
|
||||
private final float mapWidth;
|
||||
private final float mapHeight;
|
||||
|
||||
MapZoomControllerListener(MapGestureDetector detector, UiSettings uiSettings, Transform transform,
|
||||
CameraChangeDispatcher dispatcher, float mapWidth, float mapHeight) {
|
||||
MapZoomControllerListener(MapGestureDetector detector, CameraChangeDispatcher dispatcher,
|
||||
float mapWidth, float mapHeight) {
|
||||
this.mapGestureDetector = detector;
|
||||
this.uiSettings = uiSettings;
|
||||
this.transform = transform;
|
||||
this.cameraChangeDispatcher = dispatcher;
|
||||
this.mapWidth = mapWidth;
|
||||
this.mapHeight = mapHeight;
|
||||
@@ -1064,9 +1059,9 @@ public class MapView extends FrameLayout {
|
||||
focalPoint = new PointF(mapWidth / 2, mapHeight / 2);
|
||||
}
|
||||
if (zoomIn) {
|
||||
transform.zoomIn(focalPoint);
|
||||
mapGestureDetector.zoomInAnimated(focalPoint, true);
|
||||
} else {
|
||||
transform.zoomOut(focalPoint);
|
||||
mapGestureDetector.zoomOutAnimated(focalPoint, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,24 +226,8 @@ final class Transform implements MapView.OnMapChangedListener {
|
||||
return mapView.getZoom();
|
||||
}
|
||||
|
||||
void zoomIn(@NonNull PointF focalPoint) {
|
||||
CameraPosition cameraPosition = invalidateCameraPosition();
|
||||
if (cameraPosition != null) {
|
||||
int newZoom = (int) Math.round(cameraPosition.zoom + 1);
|
||||
setZoom(newZoom, focalPoint, MapboxConstants.ANIMATION_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
void zoomOut(@NonNull PointF focalPoint) {
|
||||
CameraPosition cameraPosition = invalidateCameraPosition();
|
||||
if (cameraPosition != null) {
|
||||
int newZoom = (int) Math.round(cameraPosition.zoom - 1);
|
||||
setZoom(newZoom, focalPoint, MapboxConstants.ANIMATION_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
void zoomBy(double zoomAddition, @NonNull PointF focalPoint) {
|
||||
setZoom(mapView.getZoom() + zoomAddition, focalPoint, 0);
|
||||
setZoom(mapView.getZoom() + zoomAddition, focalPoint);
|
||||
}
|
||||
|
||||
void setZoom(double zoom, @NonNull PointF focalPoint) {
|
||||
|
||||
Reference in New Issue
Block a user