I want to be able to detect a single click or a double click when the menu button is pressed. If a single click is detected one even will happen, if a double click is detected a different event will happen. Here is what I've tried(Using toast in place of events):
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;
}
The problem is that a single click event is detected every time before a double click eve开发者_运维问答nt.
Simple logic mistake. You are returning before recording the new lastPressTime. You should only have one return call if they are both returning the same thing:
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;
}
I modified this code to detect hold events (long clicks) as well as short and double clicks. It works by delaying detection of a short click until an ACTION_UP event, where the event has not already been handled (clickHandled == false).
Provide your own methods for onShortClick(), onLongClick() and and 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;
}
精彩评论