[android] - Add touch velocity effects on scale gesture.
This commit is contained in:
@@ -3,12 +3,14 @@ package com.mapbox.mapboxsdk.maps;
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.location.Location;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.GestureDetectorCompat;
|
||||
import android.support.v4.view.ScaleGestureDetectorCompat;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;
|
||||
@@ -59,6 +61,10 @@ final class MapGestureDetector {
|
||||
private boolean recentScaleGestureOccurred;
|
||||
private long scaleBeginTime;
|
||||
|
||||
private VelocityTracker velocityTracker = null;
|
||||
private boolean wasZoomingIn = false;
|
||||
private final Handler handler = new Handler();
|
||||
|
||||
MapGestureDetector(Context context, Transform transform, Projection projection, UiSettings uiSettings,
|
||||
TrackingSettings trackingSettings, AnnotationManager annotationManager,
|
||||
CameraChangeDispatcher cameraChangeDispatcher) {
|
||||
@@ -153,6 +159,12 @@ final class MapGestureDetector {
|
||||
// Handle two finger tap
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (velocityTracker == null) {
|
||||
velocityTracker = VelocityTracker.obtain();
|
||||
} else {
|
||||
velocityTracker.clear();
|
||||
}
|
||||
velocityTracker.addMovement(event);
|
||||
// First pointer down, reset scaleGestureOccurred, used to avoid triggering a fling after a scale gesture #7666
|
||||
recentScaleGestureOccurred = false;
|
||||
transform.setGestureInProgress(true);
|
||||
@@ -180,7 +192,8 @@ final class MapGestureDetector {
|
||||
boolean isTap = tapInterval <= ViewConfiguration.getTapTimeout();
|
||||
boolean inProgress = rotateGestureDetector.isInProgress()
|
||||
|| scaleGestureDetector.isInProgress()
|
||||
|| shoveGestureDetector.isInProgress();
|
||||
|| shoveGestureDetector.isInProgress()
|
||||
|| scaleGestureOccurred;
|
||||
|
||||
if (twoTap && isTap && !inProgress) {
|
||||
if (focalPoint != null) {
|
||||
@@ -203,11 +216,23 @@ final class MapGestureDetector {
|
||||
|
||||
twoTap = false;
|
||||
transform.setGestureInProgress(false);
|
||||
if (velocityTracker != null) {
|
||||
velocityTracker.recycle();
|
||||
}
|
||||
velocityTracker = null;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
twoTap = false;
|
||||
transform.setGestureInProgress(false);
|
||||
if (velocityTracker != null) {
|
||||
velocityTracker.recycle();
|
||||
}
|
||||
velocityTracker = null;
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
velocityTracker.addMovement(event);
|
||||
velocityTracker.computeCurrentVelocity(1000);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -450,10 +475,22 @@ final class MapGestureDetector {
|
||||
// Called when fingers leave screen
|
||||
@Override
|
||||
public void onScaleEnd(ScaleGestureDetector detector) {
|
||||
scaleGestureOccurred = false;
|
||||
scaleBeginTime = 0;
|
||||
scaleFactor = 1.0f;
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
double velocityXY = Math.abs(velocityTracker.getYVelocity()) + Math.abs(velocityTracker.getXVelocity());
|
||||
if (velocityXY > MapboxConstants.VELOCITY_THRESHOLD_IGNORE_FLING) {
|
||||
long animationTime = (long)(Math.log(velocityXY) * 66);
|
||||
transform.zoom(wasZoomingIn, new PointF(detector.getFocusX(), detector.getFocusY()), animationTime);
|
||||
handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scaleGestureOccurred = false;
|
||||
}
|
||||
}, animationTime);
|
||||
} else {
|
||||
scaleGestureOccurred = false;
|
||||
scaleBeginTime = 0;
|
||||
scaleFactor = 1.0f;
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
}
|
||||
}
|
||||
|
||||
// Called each time a finger moves
|
||||
@@ -500,6 +537,7 @@ final class MapGestureDetector {
|
||||
|
||||
trackingSettings.resetTrackingModesIfRequired(!quickZoom, false, false);
|
||||
// Scale the map
|
||||
wasZoomingIn = (Math.log(detector.getScaleFactor()) / Math.log(Math.PI / 2)) >= 0;
|
||||
if (focalPoint != null) {
|
||||
// arround user provided focal point
|
||||
transform.zoomBy(Math.log(detector.getScaleFactor()) / Math.log(Math.PI / 2), focalPoint.x, focalPoint.y);
|
||||
|
||||
@@ -221,6 +221,17 @@ final class Transform implements MapView.OnMapChangedListener {
|
||||
}
|
||||
}
|
||||
|
||||
void zoom(boolean zoomIn, @NonNull PointF focalPoint,long duration) {
|
||||
CameraPosition cameraPosition = invalidateCameraPosition();
|
||||
if (cameraPosition != null) {
|
||||
int newZoom = (int) Math.round(cameraPosition.zoom + (zoomIn ? 1 : -1));
|
||||
setZoom(newZoom, focalPoint, duration);
|
||||
} else {
|
||||
// we are not transforming, notify about being idle
|
||||
cameraChangeDispatcher.onCameraIdle();
|
||||
}
|
||||
}
|
||||
|
||||
void setZoom(double zoom, @NonNull PointF focalPoint) {
|
||||
setZoom(zoom, focalPoint, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user