Как я могу создать событие одного клика и событие двойного щелчка при нажатии кнопки меню? - PullRequest
1 голос
/ 01 сентября 2011

Я хочу иметь возможность обнаруживать один или два щелчка при нажатии кнопки меню. Если обнаружен один щелчок, произойдет даже одно, а при двойном щелчке произойдет другое событие. Вот что я попробовал (используя тост вместо событий):

private static final long DOUBLE_PRESS_INTERVAL = 250; // in millis
private long lastPressTime;

@Override
public boolean onPrepareOptionsMenu(Menu menu) {    

    // Get current time in nano seconds.
    long pressTime = System.currentTimeMillis();


    // If double click...
    if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) {
        Toast.makeText(getApplicationContext(), "Double Click Event", Toast.LENGTH_SHORT).show();
        return true;
    }

    // If not double click....
    Toast.makeText(getApplicationContext(), "Single Click Event", Toast.LENGTH_SHORT).show();

    // record the last time the menu button was pressed.
    lastPressTime = pressTime;      
    return true;
}

Проблема в том, что каждый раз перед событием двойного щелчка обнаруживается одно нажатие.

Ответы [ 2 ]

14 голосов
/ 01 сентября 2011

Простая логическая ошибка.Вы возвращаетесь перед записью нового lastPressTime.Вы должны иметь только один обратный вызов, если они оба возвращают одну и ту же вещь:

boolean mHasDoubleClicked = false;

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {    

        // Get current time in nano seconds.
        long pressTime = System.currentTimeMillis();


        // If double click...
        if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) {
            Toast.makeText(getApplicationContext(), "Double Click Event", Toast.LENGTH_SHORT).show();
            mHasDoubleClicked = true;
        }
        else {     // If not double click....
            mHasDoubleClicked = false;
            Handler myHandler = new Handler() {
                 public void handleMessage(Message m) {
                      if (!mHasDoubleClicked) {
                            Toast.makeText(getApplicationContext(), "Single Click Event", Toast.LENGTH_SHORT).show();
                      }
                 }
            };
            Message m = new Message();
            myHandler.sendMessageDelayed(m,DOUBLE_PRESS_INTERVAL);
        }
        // record the last time the menu button was pressed.
        lastPressTime = pressTime;      
        return true;
    }
1 голос
/ 13 марта 2016

Я изменил этот код, чтобы обнаруживать события удержания (длинные щелчки), а также короткие и двойные щелчки. Он работает, задерживая обнаружение короткого щелчка до события ACTION_UP, где событие еще не было обработано (clickHandled == false).

Предоставьте свои собственные методы для onShortClick (), onLongClick () и onDoubleClick ().

private long thisTouchTime;
private long previousTouchTime = 0;
private long buttonHeldTime;
private boolean clickHandled = false;
private long DOUBLE_CLICK_INTERVAL = ViewConfiguration.getDoubleTapTimeout();
private long LONG_HOLD_TIMEOUT = ViewConfiguration.getLongPressTimeout();

@Override
public boolean onTouch(View v, final MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            thisTouchTime = System.currentTimeMillis();
            if (thisTouchTime - previousTouchTime <= DOUBLE_CLICK_INTERVAL) {
                // double click detected
                clickHandled = true;
                onDoubleClick(event);
            } else {
                // defer event handling until later
                clickHandled = false;
            }
            previousTouchTime = thisTouchTime;
            break;
        case MotionEvent.ACTION_UP:
            if (!clickHandled) {
                buttonHeldTime = System.currentTimeMillis() - thisTouchTime;
                if (buttonHeldTime > LONG_HOLD_TIMEOUT) {
                    clickHandled = true;
                    onLongClick(event);
                } else {
                    Handler myHandler = new Handler() {
                        public void handleMessage(Message m) {
                            if (!clickHandled) {
                                clickHandled = true;
                                onShortClick(event);
                            }
                        }
                    };
                    Message m = new Message();
                    myHandler.sendMessageDelayed(m, DOUBLE_CLICK_INTERVAL);
                }
            }
            break;
        case MotionEvent.ACTION_MOVE:
            myParams.x = initialDrawX + (int) (event.getRawX() - initialTouchX);
            myParams.y = initialDrawY + (int) (event.getRawY() - initialTouchY);
            windowManager.updateViewLayout(v, myParams);
            break;
    }
    return false;
}
...