Camera callbacks for velocity animated movements (#10925)
* [android] camera listeners double invocation fix * [android] invoking camera change callbacks for velocity animated movements
This commit is contained in:
@@ -34,6 +34,11 @@ class CameraChangeDispatcher implements MapboxMap.OnCameraMoveStartedListener, M
|
||||
private final Runnable onCameraMoveStartedRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!idle) {
|
||||
return;
|
||||
}
|
||||
idle = false;
|
||||
|
||||
// deprecated API
|
||||
if (onCameraMoveStartedListener != null) {
|
||||
onCameraMoveStartedListener.onCameraMoveStarted(moveStartedReason);
|
||||
@@ -85,6 +90,11 @@ class CameraChangeDispatcher implements MapboxMap.OnCameraMoveStartedListener, M
|
||||
private final Runnable onCameraIdleRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (idle) {
|
||||
return;
|
||||
}
|
||||
idle = true;
|
||||
|
||||
// deprecated API
|
||||
if (onCameraIdleListener != null) {
|
||||
onCameraIdleListener.onCameraIdle();
|
||||
@@ -121,67 +131,23 @@ class CameraChangeDispatcher implements MapboxMap.OnCameraMoveStartedListener, M
|
||||
|
||||
@Override
|
||||
public void onCameraMoveStarted(final int reason) {
|
||||
if (!idle) {
|
||||
return;
|
||||
}
|
||||
idle = false;
|
||||
moveStartedReason = reason;
|
||||
handler.post(onCameraMoveStartedRunnable);
|
||||
|
||||
// new API
|
||||
if (!onCameraMoveStarted.isEmpty()) {
|
||||
for (OnCameraMoveStartedListener cameraMoveStartedListener : onCameraMoveStarted) {
|
||||
cameraMoveStartedListener.onCameraMoveStarted(reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraMove() {
|
||||
handler.post(onCameraMoveRunnable);
|
||||
if (onCameraMoveListener != null && !idle) {
|
||||
onCameraMoveListener.onCameraMove();
|
||||
}
|
||||
|
||||
// new API
|
||||
if (!onCameraMove.isEmpty() && !idle) {
|
||||
for (OnCameraMoveListener cameraMoveListener : onCameraMove) {
|
||||
cameraMoveListener.onCameraMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraMoveCanceled() {
|
||||
handler.post(onCameraMoveCancelRunnable);
|
||||
if (onCameraMoveCanceledListener != null && !idle) {
|
||||
onCameraMoveCanceledListener.onCameraMoveCanceled();
|
||||
}
|
||||
|
||||
// new API
|
||||
if (!onCameraMoveCanceled.isEmpty() && !idle) {
|
||||
for (OnCameraMoveCanceledListener cameraMoveCanceledListener : onCameraMoveCanceled) {
|
||||
cameraMoveCanceledListener.onCameraMoveCanceled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraIdle() {
|
||||
if (!idle) {
|
||||
idle = true;
|
||||
handler.post(onCameraIdleRunnable);
|
||||
if (onCameraIdleListener != null) {
|
||||
onCameraIdleListener.onCameraIdle();
|
||||
}
|
||||
|
||||
// new API
|
||||
if (!onCameraIdle.isEmpty()) {
|
||||
for (OnCameraIdleListener cameraIdleListener : onCameraIdle) {
|
||||
cameraIdleListener.onCameraIdle();
|
||||
}
|
||||
}
|
||||
}
|
||||
handler.post(onCameraIdleRunnable);
|
||||
}
|
||||
|
||||
void addOnCameraIdleListener(@NonNull OnCameraIdleListener listener) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.mapbox.services.android.telemetry.utils.TelemetryUtils;
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener.REASON_API_ANIMATION;
|
||||
import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener.REASON_API_GESTURE;
|
||||
|
||||
/**
|
||||
@@ -78,9 +79,11 @@ final class MapGestureDetector {
|
||||
|
||||
private boolean scaleGestureOccurred;
|
||||
private boolean recentScaleGestureOccurred;
|
||||
private boolean scaleAnimating;
|
||||
private long scaleBeginTime;
|
||||
|
||||
private boolean scaleAnimating;
|
||||
private boolean rotateAnimating;
|
||||
|
||||
private VelocityTracker velocityTracker;
|
||||
private boolean wasZoomingIn;
|
||||
private boolean wasClockwiseRotating;
|
||||
@@ -233,7 +236,10 @@ final class MapGestureDetector {
|
||||
MapboxTelemetry.getInstance().pushEvent(MapboxEventWrapper.buildMapDragEndEvent(
|
||||
getLocationFromGesture(event.getX(), event.getY()), transform));
|
||||
scrollGestureOccurred = false;
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
|
||||
if (!scaleAnimating && !rotateAnimating) {
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
}
|
||||
}
|
||||
|
||||
twoTap = false;
|
||||
@@ -615,7 +621,6 @@ final class MapGestureDetector {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (rotateGestureOccurred || quickZoom) {
|
||||
reset();
|
||||
return;
|
||||
@@ -657,13 +662,23 @@ final class MapGestureDetector {
|
||||
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
transform.setZoom((Float) animation.getAnimatedValue(), scalePointBegin);
|
||||
transform.setZoom((Float) animation.getAnimatedValue(), scalePointBegin, 0, true);
|
||||
}
|
||||
});
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_ANIMATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
reset();
|
||||
}
|
||||
});
|
||||
@@ -682,7 +697,6 @@ final class MapGestureDetector {
|
||||
|
||||
private long beginTime = 0;
|
||||
private boolean started = false;
|
||||
private boolean animating = false;
|
||||
|
||||
// Called when two fingers first touch the screen
|
||||
@Override
|
||||
@@ -753,9 +767,9 @@ final class MapGestureDetector {
|
||||
}
|
||||
|
||||
double angularVelocity = calculateVelocityVector(detector);
|
||||
if (Math.abs(angularVelocity) > 0.001 && rotateGestureOccurred && !animating) {
|
||||
if (Math.abs(angularVelocity) > 0.001 && rotateGestureOccurred && !rotateAnimating) {
|
||||
animateRotateVelocity();
|
||||
} else if (!animating) {
|
||||
} else if (!rotateAnimating) {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
@@ -763,12 +777,16 @@ final class MapGestureDetector {
|
||||
private void reset() {
|
||||
beginTime = 0;
|
||||
started = false;
|
||||
animating = false;
|
||||
rotateAnimating = false;
|
||||
rotateGestureOccurred = false;
|
||||
|
||||
if (!twoTap) {
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
}
|
||||
}
|
||||
|
||||
private void animateRotateVelocity() {
|
||||
animating = true;
|
||||
rotateAnimating = true;
|
||||
double currentRotation = transform.getRawBearing();
|
||||
double rotateAdditionDegrees = calculateVelocityInDegrees();
|
||||
createAnimator(currentRotation, rotateAdditionDegrees).start();
|
||||
@@ -811,9 +829,19 @@ final class MapGestureDetector {
|
||||
}
|
||||
});
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
cameraChangeDispatcher.onCameraMoveStarted(REASON_API_ANIMATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
reset();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -239,7 +239,7 @@ final class Transform implements MapView.OnMapChangedListener {
|
||||
CameraPosition cameraPosition = invalidateCameraPosition();
|
||||
if (cameraPosition != null) {
|
||||
int newZoom = (int) Math.round(cameraPosition.zoom + (zoomIn ? 1 : -1));
|
||||
setZoom(newZoom, focalPoint, MapboxConstants.ANIMATION_DURATION);
|
||||
setZoom(newZoom, focalPoint, MapboxConstants.ANIMATION_DURATION, false);
|
||||
} else {
|
||||
// we are not transforming, notify about being idle
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
@@ -250,7 +250,7 @@ final class Transform implements MapView.OnMapChangedListener {
|
||||
CameraPosition cameraPosition = invalidateCameraPosition();
|
||||
if (cameraPosition != null) {
|
||||
int newZoom = (int) Math.round(cameraPosition.zoom + zoomAddition);
|
||||
setZoom(newZoom, focalPoint, duration);
|
||||
setZoom(newZoom, focalPoint, duration, false);
|
||||
} else {
|
||||
// we are not transforming, notify about being idle
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
@@ -258,16 +258,18 @@ final class Transform implements MapView.OnMapChangedListener {
|
||||
}
|
||||
|
||||
void setZoom(double zoom, @NonNull PointF focalPoint) {
|
||||
setZoom(zoom, focalPoint, 0);
|
||||
setZoom(zoom, focalPoint, 0, false);
|
||||
}
|
||||
|
||||
void setZoom(double zoom, @NonNull PointF focalPoint, long duration) {
|
||||
void setZoom(double zoom, @NonNull PointF focalPoint, long duration, boolean isAnimator) {
|
||||
if (mapView != null) {
|
||||
mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
|
||||
@Override
|
||||
public void onMapChanged(int change) {
|
||||
if (change == MapView.REGION_DID_CHANGE_ANIMATED) {
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
if (!isAnimator) {
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
}
|
||||
mapView.removeOnMapChangedListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user