Подтвердить что ты не робот

Почему android onLongPress всегда запускается после onDoubleTap?

У меня есть действия onLongPress и onDoubleTap, размещенные на кнопке в соответствии с этим кодом:

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

Я всегда вижу onLongPress, который запускается после того, как onDoubleClick запущен и выполнен. В чем причина такого противоречивого поведения и как его избежать?

ОБНОВЛЕНО Я изменил свой исходный код, чтобы быть более конкретным

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

Это журнал после onDoubleTap, который я нажал. Вы можете увидеть 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 *************

UPDATE Я нашел решение. Чтобы избежать срабатывания onLongPress, необходимо выполнить два:

Сначала: detector.setIsLongpressEnabled(true); в onTouch (просмотр v, событие MotionEvent)

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

Во-вторых: add detector.setIsLongpressEnabled(false); in onDoubleTap (MotionEvent e)

     public boolean onDoubleTap(MotionEvent e) {
        detector.setIsLongpressEnabled(false);
        System.out.println("************* onDoubleTap *************");  
        Intent intent = new Intent();        
        intent.setClass(getApplicationContext(), NewActivity.class);
        intent.putExtra("parameterName", "parameter");
        startActivity(intent);             
        return true;
    }
4b9b3361

Ответ 1

Технически это не должно происходить

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 все сообщения LONG_PRESS удаляются из очереди. Таким образом, при втором нажатии следующий код удалит длительные события.

 mHandler.removeMessages(LONG_PRESS);

Ninja edit: hacky обходной путь для вашей проблемы

     @Override
     public void onLongPress(MotionEvent e) {
        if(MainActivity.this.hasWindowFocus())
        {
            Log.d("Touchy", "Long tap");    
        }
    }

Ответ 2

Вы всегда видите, что onLongPress уволен, потому что в вашем коде вы запускаете намерение прежде, чем использовать событие onDoubleTap.
Вы можете отключить onLongPress с помощью public void setIsLongpressEnabled (boolean isLongpressEnabled)
и используйте метод onDown для выполнения вашего действия.