天天看点

android实现双击监听

方案的优势:

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());
}