This commit is contained in:
Alexey Kulish 2016-07-01 16:03:33 +03:00
parent d5716fa8c6
commit f5163ea7fe
3 changed files with 46 additions and 56 deletions

View file

@ -3,9 +3,6 @@ package net.osmand.plus.helpers;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
/**
* Created by Barsik on 24.06.2014.
*/
public abstract class TwoFingerTapDetector {
private static final int TIMEOUT = ViewConfiguration.getTapTimeout() + 100;
private long mFirstDownTime = 0;

View file

@ -18,14 +18,14 @@ import org.apache.commons.logging.Log;
public class DoubleTapScaleDetector {
private static final Log LOG = PlatformUtil.getLog(DoubleTapScaleDetector.class);
private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
private static final int DOUBLE_TAP_MIN_TIME = 40;
private static final int LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
public static final int SCALE_PER_SCREEN = 4;
private final DoubleTapZoomListener listener;
protected final Context ctx;
private int displayHeightPx;
private PointF centerScreen;
private boolean mIsInZoomMode = false;
private float scale;
@ -43,33 +43,41 @@ public class DoubleTapScaleDetector {
Point size = new Point();
defaultDisplay.getSize(size);
displayHeightPx = size.y;
centerScreen = new PointF(size.x / 2, size.y / 2);
} else {
displayHeightPx = defaultDisplay.getHeight();
centerScreen = new PointF(defaultDisplay.getWidth() / 2, defaultDisplay.getHeight() / 2);
}
final ViewConfiguration configuration = ViewConfiguration.get(ctx);
int doubleTapSlop = (int) (configuration.getScaledTouchSlop() * 1.5);
int doubleTapSlop = (int) (configuration.getScaledDoubleTapSlop() * 0.5);
mDoubleTapSlopSquare = doubleTapSlop * doubleTapSlop;
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getPointerCount() != 1) {
resetEvents();
mIsDoubleTapping = false;
return false;
}
long currentTime = System.currentTimeMillis();
if (event.getAction() == MotionEvent.ACTION_UP) {
boolean handled = false;
if (mIsInZoomMode) {
mIsInZoomMode = false;
listener.onZoomEnded(scale);
handled = true;
} else if (secondDown != null) {
if (calculateSqaredDistance(secondDown, event) < mDoubleTapSlopSquare
&& event.getEventTime() - secondDown.getEventTime() < LONG_PRESS_TIMEOUT) {
listener.onDoubleTap(event);
}
handled = true;
} else {
firstUp = MotionEvent.obtain(event);
}
if (secondDown != null &&
calculateSqaredDistance(secondDown, event) < mDoubleTapSlopSquare) {
listener.onDoubleTap(event);
if (handled) {
resetEvents();
}
secondDown = null;
mIsDoubleTapping = false;
return handled;
} else {
@ -80,7 +88,7 @@ public class DoubleTapScaleDetector {
float x = event.getX();
float y = event.getY();
listener.onGestureInit(x, y, x, y);
listener.onZoomStarted(new PointF(x, y));
listener.onZoomStarted(centerScreen);
return true;
} else {
firstDown = MotionEvent.obtain(event);
@ -101,6 +109,12 @@ public class DoubleTapScaleDetector {
return false;
}
private void resetEvents() {
firstUp = null;
firstDown = null;
secondDown = null;
}
public boolean isInZoomMode() {
return mIsInZoomMode;
}
@ -113,35 +127,29 @@ public class DoubleTapScaleDetector {
return Math.round(px / (Resources.getSystem().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
private final boolean isConsideredDoubleTap(MotionEvent firstDown,
MotionEvent firstUp,
MotionEvent secondDown) {
private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp,
MotionEvent secondDown) {
if (firstDown == null || firstUp == null || secondDown == null) {
return false;
}
final long deltaTime = secondDown.getEventTime() - firstUp.getEventTime();
if (deltaTime > DOUBLE_TAP_TIMEOUT || deltaTime < DOUBLE_TAP_MIN_TIME) {
if (secondDown.getEventTime() - firstUp.getEventTime() > DOUBLE_TAP_TIMEOUT) {
return false;
}
int squaredDown = calculateSqaredDistance(firstDown, secondDown);
int squaredUp = calculateSqaredDistance(firstUp, secondDown);
return squaredDown < mDoubleTapSlopSquare && squaredUp < mDoubleTapSlopSquare;
return calculateSqaredDistance(firstDown, secondDown) < mDoubleTapSlopSquare;
}
private static int calculateSqaredDistance(MotionEvent first,
private int calculateSqaredDistance(MotionEvent first,
MotionEvent second) {
int deltaXDown = (int) first.getX() - (int) second.getX();
int deltaYDown = (int) first.getY() - (int) second.getY();
return deltaXDown * deltaXDown + deltaYDown * deltaYDown;
}
private static final boolean isConfirmedScale(MotionEvent secondDown,
MotionEvent moveEvent) {
private boolean isConfirmedScale(MotionEvent secondDown, MotionEvent moveEvent) {
if (secondDown == null || moveEvent == null) {
return false;
}
return moveEvent.getEventTime() - secondDown.getEventTime() > TAP_TIMEOUT - 50;
return calculateSqaredDistance(secondDown, moveEvent) > mDoubleTapSlopSquare;
}
public float getCenterX() {

View file

@ -11,15 +11,12 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.InputDevice;
@ -142,10 +139,6 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
private AnimateDraggingMapThread animatedDraggingThread;
private GestureDetector gestureDetector;
private MultiTouchSupport multiTouchSupport;
Paint paintGrayFill;
Paint paintBlackFill;
Paint paintWhiteFill;
@ -160,19 +153,11 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
private Paint paintImg;
private boolean afterTwoFingerTap = false;
private GestureDetector gestureDetector;
private MultiTouchSupport multiTouchSupport;
private DoubleTapScaleDetector doubleTapScaleDetector;
TwoFingerTapDetector twoFingerTapDetector = new TwoFingerTapDetector() {
@Override
public void onTwoFingerTap() {
afterTwoFingerTap = true;
if (isZoomingAllowed(getZoom(), -1)) {
getAnimatedDraggingThread().startZooming(getZoom() - 1, currentViewport.getZoomFloatPart(), true);
}
}
};
private int displayHeightPx;
private TwoFingerTapDetector twoFingersTapDetector;
private boolean afterTwoFingersTap = false;
public OsmandMapTileView(MapActivity activity, int w, int h) {
this.activity = activity;
@ -218,6 +203,15 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
gestureDetector = new GestureDetector(ctx, new MapTileViewOnGestureListener());
multiTouchSupport = new MultiTouchSupport(ctx, new MapTileViewMultiTouchZoomListener());
doubleTapScaleDetector = new DoubleTapScaleDetector(activity, new MapTileViewMultiTouchZoomListener());
twoFingersTapDetector = new TwoFingerTapDetector() {
@Override
public void onTwoFingerTap() {
afterTwoFingersTap = true;
if (isZoomingAllowed(getZoom(), -1)) {
getAnimatedDraggingThread().startZooming(getZoom() - 1, currentViewport.getZoomFloatPart(), true);
}
}
};
WindowManager mgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
dm = new DisplayMetrics();
@ -228,15 +222,6 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
setPixelDimensions(w, h).build();
currentViewport.setDensity(dm.density);
currentViewport.setMapDensity(getSettingsMapDensity());
Display defaultDisplay = ctx.getWindowManager().getDefaultDisplay();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
Point size = new Point();
defaultDisplay.getSize(size);
displayHeightPx = size.y;
} else {
displayHeightPx = defaultDisplay.getHeight();
}
}
public void setView(View view) {
@ -827,7 +812,7 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
mapRenderer.resumeSymbolsUpdate();
}
}
if (twoFingerTapDetector.onTouchEvent(event)) {
if (twoFingersTapDetector.onTouchEvent(event)) {
ContextMenuLayer contextMenuLayer = getLayerByClass(ContextMenuLayer.class);
if (contextMenuLayer != null) {
contextMenuLayer.onTouchEvent(event, getCurrentRotatedTileBox());
@ -1068,8 +1053,8 @@ public class OsmandMapTileView implements IMapDownloaderCallback {
public void onLongPress(MotionEvent e) {
if (multiTouchSupport.isInZoomMode()
|| doubleTapScaleDetector.isInZoomMode()
|| afterTwoFingerTap) {
afterTwoFingerTap = false;
|| afterTwoFingersTap) {
afterTwoFingersTap = false;
return;
}
if (LOG.isDebugEnabled()) {