This source file includes following definitions.
- onTap
- onLongPress
- handleMessage
- onTouchEvent
- trackDownEvent
- trackUpEvent
- trackMoveEvent
- reset
- cancelLongTouchNotification
package org.chromium.chromoting;
import android.content.Context;
import android.graphics.PointF;
import android.os.Handler;
import android.os.Message;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
public class TapGestureDetector {
public interface OnTapListener {
boolean onTap(int pointerCount);
void onLongPress(int pointerCount);
}
private OnTapListener mListener;
private Handler mHandler;
private int mPointerCount = 0;
private SparseArray<PointF> mInitialPositions = new SparseArray<PointF>();
private int mTouchSlopSquare;
private boolean mTapCancelled = false;
private class EventHandler extends Handler {
@Override
public void handleMessage(Message message) {
mListener.onLongPress(mPointerCount);
mTapCancelled = true;
}
}
public TapGestureDetector(Context context, OnTapListener listener) {
mListener = listener;
mHandler = new EventHandler();
ViewConfiguration config = ViewConfiguration.get(context);
int touchSlop = config.getScaledTouchSlop();
mTouchSlopSquare = touchSlop * touchSlop;
}
public boolean onTouchEvent(MotionEvent event) {
boolean handled = false;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
reset();
mHandler.sendEmptyMessageDelayed(0, ViewConfiguration.getLongPressTimeout());
trackDownEvent(event);
mPointerCount = 1;
break;
case MotionEvent.ACTION_POINTER_DOWN:
trackDownEvent(event);
mPointerCount = Math.max(mPointerCount, event.getPointerCount());
break;
case MotionEvent.ACTION_MOVE:
if (!mTapCancelled) {
if (trackMoveEvent(event)) {
cancelLongTouchNotification();
mTapCancelled = true;
}
}
break;
case MotionEvent.ACTION_UP:
cancelLongTouchNotification();
if (!mTapCancelled) {
handled = mListener.onTap(mPointerCount);
}
break;
case MotionEvent.ACTION_POINTER_UP:
cancelLongTouchNotification();
trackUpEvent(event);
break;
case MotionEvent.ACTION_CANCEL:
cancelLongTouchNotification();
break;
default:
break;
}
return handled;
}
private void trackDownEvent(MotionEvent event) {
int pointerIndex = 0;
if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
pointerIndex = event.getActionIndex();
}
int pointerId = event.getPointerId(pointerIndex);
mInitialPositions.put(pointerId,
new PointF(event.getX(pointerIndex), event.getY(pointerIndex)));
}
private void trackUpEvent(MotionEvent event) {
int pointerIndex = 0;
if (event.getActionMasked() == MotionEvent.ACTION_POINTER_UP) {
pointerIndex = event.getActionIndex();
}
int pointerId = event.getPointerId(pointerIndex);
mInitialPositions.remove(pointerId);
}
private boolean trackMoveEvent(MotionEvent event) {
int pointerCount = event.getPointerCount();
for (int i = 0; i < pointerCount; i++) {
int pointerId = event.getPointerId(i);
float currentX = event.getX(i);
float currentY = event.getY(i);
PointF downPoint = mInitialPositions.get(pointerId);
if (downPoint == null) {
mInitialPositions.put(pointerId, new PointF(currentX, currentY));
continue;
}
float deltaX = currentX - downPoint.x;
float deltaY = currentY - downPoint.y;
if (deltaX * deltaX + deltaY * deltaY > mTouchSlopSquare) {
return true;
}
}
return false;
}
private void reset() {
cancelLongTouchNotification();
mPointerCount = 0;
mInitialPositions.clear();
mTapCancelled = false;
}
private void cancelLongTouchNotification() {
mHandler.removeMessages(0);
}
}