如何在Android中实现双指双击?

WOU*_*nes 7 android double-click multi-touch gesture

我知道如何检测双击和双指触摸事件,但我怎样才能将这些结合起来做出反应,这样有人需要用两根手指双击?

默认情况下,Android有长按作为第二种点击形式,但我特意寻找双指双击.

Sam*_*Sam 14

我想要一个简单且可重复使用的界面,它可以监听两个手指双击并且表现得像GestureDetector.这样就可以像这样使用它(所有剪切和粘贴的可运行代码):

public class Example extends Activity {
    SimpleTwoFingerDoubleTapDetector multiTouchListener = new SimpleTwoFingerDoubleTapDetector() {
        @Override
        public void onTwoFingerDoubleTap() {
            // Do what you want here, I used a Toast for demonstration
            Toast.makeText(Example.this, "Two Finger Double Tap", Toast.LENGTH_SHORT).show();
        }
    };

    // Override onCreate() and anything else you want

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(multiTouchListener.onTouchEvent(event))
            return true;
        return super.onTouchEvent(event);
    }
}
Run Code Online (Sandbox Code Playgroud)

我创建了SimpleTwoFingerDoubleTapDetector.(这是一个很长的名称,但它是描述性的.您可以将其重命名为您想要的任何内容.)将此新文件保存在项目中或作为库:

public abstract class SimpleTwoFingerDoubleTapDetector {
    private static final int TIMEOUT = ViewConfiguration.getDoubleTapTimeout() + 100;
    private long mFirstDownTime = 0;
    private boolean mSeparateTouches = false;
    private byte mTwoFingerTapCount = 0;

    private void reset(long time) {
        mFirstDownTime = time;
        mSeparateTouches = false;
        mTwoFingerTapCount = 0;
    }

    public boolean onTouchEvent(MotionEvent event) {
        switch(event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
            if(mFirstDownTime == 0 || event.getEventTime() - mFirstDownTime > TIMEOUT) 
                reset(event.getDownTime());
            break;
        case MotionEvent.ACTION_POINTER_UP:
            if(event.getPointerCount() == 2)  
                mTwoFingerTapCount++;
            else 
                mFirstDownTime = 0;
            break;
        case MotionEvent.ACTION_UP:
            if(!mSeparateTouches)
                mSeparateTouches = true;
            else if(mTwoFingerTapCount == 2 && event.getEventTime() - mFirstDownTime < TIMEOUT) {
                onTwoFingerDoubleTap();
                mFirstDownTime = 0;
                return true;
            }
        }               

        return false;
    }

    public abstract void onTwoFingerDoubleTap();
}
Run Code Online (Sandbox Code Playgroud)

首先,关于Android(一键式)GestureDetector的一些注意事项:

  • Android的onDoubleTap()事件使用ViewConfiguration的标准超时值.我指的是同一时间.
  • 它们测量从第一次敲击手指向下事件到第二次敲击手指向下事件所经过的时间,然后广播onDoubleTap()onDoubleTapEvent().
    • onDoubleTap() 仅在第二次敲击手指向下事件发生时触发.
    • onDoubleTapEvent() 通过第二次点击为每个动作触发:向下,向上和向上.

关于SimpleTwoFingerDoubleTapDetector的一些注意事项:

  • 我的超时是从第一个手指向下事件到最后一个手指向上事件测量的,以防止错误的双击通知.我为默认的ViewConfiguration双击超时添加了一点额外的时间来解释这个问题.
  • Android的GestureDetector测量slop(两个水龙头相隔多远).我没有看到这里的需要,也没有检查每个水龙头上两个手指之间的距离.
  • 我只播放一个活动onTwoFingerDoubleTap().

最后说明: 您可以轻松地将其更改为OnTouchListener:

  1. 更改SimpleTwoFingerDoubleTapDetector的定义:

    public abstract class SimpleTwoFingerDoubleTapListener implements OnTouchListener {
    
    Run Code Online (Sandbox Code Playgroud)
  2. 添加一个新的类变量:

    private View mFirstView;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 改变ACTION_DOWN案例:

    case MotionEvent.ACTION_DOWN:
        if(mFirstDownTime == -1 || mFirstView != v || hasTimedOut(event.getEventTime())) {
            mFirstView = v;
            reset(event.getDownTime());
        }
        break;
    
    Run Code Online (Sandbox Code Playgroud)
  4. 通过案件mFirstView内部ACTION_UP:

    onTwoFingerDoubleTap(mFirstView);
    
    Run Code Online (Sandbox Code Playgroud)
  5. 最后,更改onTwoFingerDoubleTap()方法以反映点击了哪个View:

    public abstract void onTwoFingerDoubleTap(View v);
    
    Run Code Online (Sandbox Code Playgroud)

  • 我已经尝试过这段代码(谢谢!)但它没有用 - 我只收到了ACTION_DOWN事件.我相信onTouchEvent()函数必须返回True(对于ACTION_DOWN),否则之后不会收到ACTION_UP.请参阅:http://stackoverflow.com/a/16495363/1277048 (2认同)