In an application I\'m working on, I have the requirement that a user must click & hold a component for a period time before a certain action occurs.
I\'m curren
This is the simplest way that I have found to achieve this behavior. It has a couple of advantages over the currently accepted answer.
view.isPressed we ensure that the onClick and onLongClick are not triggered if the touch event leaves the view. This mimics the default onClick and onLongClick behavior of the system.ACTION_DOWN or calculate the current time on ACTION_UP ourselves. This means that we can use it for multiple views at the same time because we aren't tracking the event start time in a single variable outside of onTouch.NOTE: ViewConfiguration.getLongPressTimeout() is the default and you can change that check to use any value you want.
NOTE: If the view is not normally clickable you will need to call view.setClickable(true) for the view.isPressed() check to work.
@Override
public boolean onTouch(View view, MotionEvent event) {
if (view.isPressed() && event.getAction() == MotionEvent.ACTION_UP) {
long eventDuration = event.getEventTime() - event.getDownTime();
if (eventDuration > ViewConfiguration.getLongPressTimeout()) {
onLongClick(view);
} else {
onClick(view);
}
}
return false;
}
If you, like @ampersandre, would like the long click event to trigger immediately once the delay period is reached instead of waiting for ACTION_UP then the following works well for me.
@Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
view.setTag(true);
} else if (view.isPressed() && (boolean) view.getTag()) {
long eventDuration = event.getEventTime() - event.getDownTime();
if (eventDuration > ViewConfiguration.getLongPressTimeout()) {
view.setTag(false);
onLongClick(view);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
onClick(view);
}
}
return false;
}