Android 为什么安卓onLongPress总是在onDoubleTap之后被解雇?

Android 为什么安卓onLongPress总是在onDoubleTap之后被解雇?,android,double-click,Android,Double Click,根据以下代码,我在按钮上仅放置了长按和长按两种操作: ... GestureDetector detector = new GestureDetector(this, new TapDetector()); public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new

根据以下代码,我在按钮上仅放置了长按和长按两种操作:

...
GestureDetector detector = new GestureDetector(this, new TapDetector());

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); 
    detector = new GestureDetector(this, new TapDetector());
    ... 
}

private class TapDetector extends GestureDetector.SimpleOnGestureListener { 

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        // Do something
        return true;
    }

    @Override
     public void onLongPress(MotionEvent e) {          
        // Do something          
    }
}

Button incomeButton = (Button) findViewById(R.id.income);
button.setOnTouchListener(new OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        detector.onTouchEvent(event);
        return true;
    }
});
我总是看到onDoubleClick启动并执行后onLongPress启动。这种违反直觉的行为的原因是什么?如何避免

已更新 我已将源代码更改为更具体的代码

public class MainActivity extends Activity { 
private GestureDetector detector;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main); 
    detector = new GestureDetector(this, new TapDetector());    

    Button button = (Button) findViewById(R.id.button);                 
    button.setOnTouchListener(new OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            System.out.println("************* onTouch *************");
            detector.onTouchEvent(event);
            return true;
        }
    });                        
}       

class TapDetector extends GestureDetector.SimpleOnGestureListener {  

    @Override
     public void onLongPress(MotionEvent e) {
        System.out.println("************* onLongPress *************");                    
    }         

    @Override
     public boolean onDoubleTap(MotionEvent e) {
        System.out.println("************* onDoubleTap *************");  
        Intent intent = new Intent();        
        intent.setClass(getApplicationContext(), NewActivity.class);
        intent.putExtra("parameterName", "parameter");
        startActivity(intent);              
        return true;
    }             
}        
}
这是我单击DoubleTap后的日志。你可以在结尾看到onLongPress,我从来没有点击过它

I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onDoubleTap *************
I/ActivityManager(   59): Starting activity: Intent { cmp=my.tapdetector/.NewActivity (has extras) }
I/ActivityManager(   59): Displayed activity my.tapdetector/.NewActivity: 324 ms (total 324 ms)
I/System.out( 1106): ************* onLongPress *************
更新我找到了解决方案。为避免仅长按点火需要进行两次更改:

第一个:detector.setIsLongpressEnabled(true);在onTouch中(视图v,运动事件)

第二:添加检测器。设置为长按启用(false);在onDoubleTap中(运动事件e)


从技术上讲,这不应该发生

case MotionEvent.ACTION_DOWN:
        mLastMotionX = x;
        mLastMotionY = y;
        mCurrentDownEvent = MotionEvent.obtain(ev);
        mAlwaysInTapRegion = true;
        mInLongPress = false;

        if (mIsLongpressEnabled) {
            mHandler.removeMessages(LONG_PRESS);
            mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
                    + tapTime + longpressTime);
        }
        mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + tapTime);
因为在ACTION_DOWN或ACTION_UP事件中,所有长消息事件都将从队列中删除。因此,在第二次点击时,以下代码将删除长按事件

 mHandler.removeMessages(LONG_PRESS);
忍者编辑:针对你的问题的黑客解决方法


您总是看到onLongPress被触发,因为在您的代码中,您在使用onDoubleTap事件之前启动了一个意图。
您可以通过
公共无效设置isLongpressEnabled(布尔值isLongpressEnabled)


并使用onDown方法执行您的操作。

抱歉,不能重复此操作。在这两个事件上使用Log.i(),它们被正确调用。请根据accepted answer的评论中所述的内置竞速条件进行适当的调整。谢谢。正如我刚才发现的,如果在onDoubleClick方法上设置了断点,我总是在onDoubleTap之后在调试器下被onLongPress激发。如果我删除断点-一切正常…这是有意义的,
mCurrentDownEvent.getDownTime()+tapTime+longpressime
到那时已经过期。似乎如果我在onDoubleTap方法中有很长时间的处理主体,我总是会被onLongPress解雇?嗯。。。所以,如果我需要在onDoubleTap方法内部进行长时间的处理,我应该做些什么来避免onLongPress触发!?由于您无权访问
mHandler
,因此无法对其执行任何操作。改用Logcat进行调试。
case MotionEvent.ACTION_DOWN:
        mLastMotionX = x;
        mLastMotionY = y;
        mCurrentDownEvent = MotionEvent.obtain(ev);
        mAlwaysInTapRegion = true;
        mInLongPress = false;

        if (mIsLongpressEnabled) {
            mHandler.removeMessages(LONG_PRESS);
            mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
                    + tapTime + longpressTime);
        }
        mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + tapTime);
 mHandler.removeMessages(LONG_PRESS);
     @Override
     public void onLongPress(MotionEvent e) {
        if(MainActivity.this.hasWindowFocus())
        {
            Log.d("Touchy", "Long tap");    
        }
    }