方案的优势:
1.灵活性高。不需要继承自View或者其子类。
2.对单击的误触进行了识别。
3.本身已经具备了双击,单击的识别机制,不必担心与原有接口的协调问题。
4.可调整单击与双击识别的时间值。
用法:
1.实例化VulcanTouchProcessor类。设置合适的监听器,以及双击的时间(单位毫秒)
2.在你的View(或者子类)的onTouch回调中调用VulcanTouchProcessor的notifyTouchUp方法
3.当双击事件触发,上述设定的监听器会被调用。
用法示例代码(其中的mTouchProcessor需要先行实例化):
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(MotionEvent.ACTION_UP == event.getAction()) {
mTouchProcessor.notifyTouchUp(v,null);
}
return true;
}
});
功能实现代码如下:
package com.vulcan.vulcan;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
/**
* Created by vulcan on 2016/12/30.
*/
public class VulcanTouchProcessor {
public static final int STATUS_READY = 0;
public static final int STATUS_GOING_TO_DOUBLE = 1;
public static final int STATUS_SLEEP = 2;//in sleep status, we do not process any key.
public static final long DEFAULT_DOUBLE_TAP_TIME_MS = 300;
public VulcanTouchProcessor(VulcanTouchListener l) {
mTouchListener = l;
}
public VulcanTouchProcessor(VulcanTouchListener l, long doubleTapTimeMs) {
this(l);
mTimeMsOfDoubleTap = doubleTapTimeMs;
}
public boolean notifyTouchUp(View v, Object extra) {
mLastTouchedView = v;
mExtraObject = extra;
if(STATUS_READY == mStatus) {
mStatus = STATUS_GOING_TO_DOUBLE;
setTimer(mTimeMsOfDoubleTap);
return true;
}
else if(STATUS_GOING_TO_DOUBLE == mStatus) {
mStatus = STATUS_SLEEP;
setTimer(mTimeMsOfSleep);
mTouchListener.onDoubleClick(v, extra);
return true;
}
else if(STATUS_SLEEP == mStatus) {
return true;
}
return true;
}
private void notifyTimeout() {
if(STATUS_READY == mStatus) {
cancelTimer();
}
else if(STATUS_GOING_TO_DOUBLE == mStatus) {
mTouchListener.onSingleClick(mLastTouchedView, mExtraObject);
setTimer(mTimeMsOfSleep);
mStatus = STATUS_SLEEP;
}
else if(STATUS_SLEEP == mStatus) {
cancelTimer();
mStatus = STATUS_READY;
}
return;
}
private void setTimer(long delayMs) {
mHandler.removeCallbacks(mTimeoutCallback);
mHandler.postDelayed(mTimeoutCallback, delayMs);
}
private void cancelTimer() {
mHandler.removeCallbacks(mTimeoutCallback);
}
private Runnable mTimeoutCallback = new Runnable() {
@Override
public void run() {
notifyTimeout();
}
};
private long mTimeMsOfSleep = 250;
private long mTimeMsOfDoubleTap = DEFAULT_DOUBLE_TAP_TIME_MS;
private Object mExtraObject;
private View mLastTouchedView;
private int mStatus = STATUS_READY;
private VulcanTouchListener mTouchListener;
private Handler mHandler = new Handler(Looper.getMainLooper());
}