Fix #2617
This commit is contained in:
parent
d5716fa8c6
commit
f5163ea7fe
3 changed files with 46 additions and 56 deletions
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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()) {
|
||||
|
|
Loading…
Reference in a new issue