Android - Detect End of Long Press

Android - Detect End of Long Press

I think your best bet is to use a combination of the onLongClickListener() and onTouchListener() for that button. You'll need to catch certain events on the touch listener since it will trigger for every touch event.

Try something like the following:

class Blah extends Activity {
private Button mSpeak;
private boolean isSpeakButtonLongPressed = false;

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.blahlayout);
Button mSpeak = (Button)findViewById(R.id.speakbutton);
mSpeak.setOnLongClickListener(speakHoldListener);
mSpeak.setOnTouchListener(speakTouchListener);
}

private View.OnLongClickListener speakHoldListener = new View.OnLongClickListener() {

@Override
public boolean onLongClick(View pView) {
// Do something when your hold starts here.
isSpeakButtonLongPressed = true;
return true;
}
}

private View.OnTouchListener speakTouchListener = new View.OnTouchListener() {

@Override
public boolean onTouch(View pView, MotionEvent pEvent) {
pView.onTouchEvent(pEvent);
// We're only interested in when the button is released.
if (pEvent.getAction() == MotionEvent.ACTION_UP) {
// We're only interested in anything if our speak button is currently pressed.
if (isSpeakButtonLongPressed) {
// Do something when the button is released.
isSpeakButtonLongPressed = false;
}
}
return false;
}
}
}

Detecting a long press in Android

Try this:

final GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
public void onLongPress(MotionEvent e) {
Log.e("", "Longpress detected");
}
});

public boolean onTouchEvent(MotionEvent event) {
return gestureDetector.onTouchEvent(event);
};

How to detect how long a button was pressed in Android?

You need to capture the time when the user presses down on the button, and the time when the user releases the button. The difference between these times is the duration of the press.

In order to achieve this, you will need to apply a View.OnTouchListener to the button, and use SystemClock.elapsedRealtime (as opposed to System.currentTimeMillis for this reason) to capture the time of the events.

button.setOnTouchListener (object : View.OnTouchListener {
var startTime = 0L
var endTime = 0L
override fun onTouch(view: View?, motionEvent: MotionEvent?): Boolean {
when (motionEvent?.action) {
MotionEvent.ACTION_DOWN -> {
// user pressed down on the button; capture start time
startTime = SystemClock.elapsedRealtime()
return true
}
MotionEvent.ACTION_CANCEL, // if user moves their finger off the button before releasing
MotionEvent.ACTION_UP -> {
// user released the button; capture end time and calculate the result
endTime = SystemClock.elapsedRealtime()
if (endTime > startTime) {
val ellapsedTime = endTime - startTime
// do something with ellapsedTime
}
return true
}
}
return false
}
})

Distinguish between short tap (click) and long press in OnTouchListener

The Android way to handle this is using a gesture detector. The guide topic Detect common gestures discusses how to do this and provides sample code.

The only reason you would want to operate at the relatively low level of a touch listener is if the logic you want to implement isn't already packaged up by one of the library gesture detectors. Fortunately for you, long press and dragging are already supported gestures.

If you want to write your own logic anyway, the source code for the appropriate gesture detectors can provide you a good starting point. However, I strongly discourage that because the logic can be very tricky, with lots of edge cases to get right.

EDIT: Okay, after reading the documentation, I confess that it isn't quite as simple as I thought. But it shouldn't be very complicated, either. The problem is clear from the documentation for setIsLongpressEnabled (emphasis added):

Set whether longpress is enabled, if this is enabled when a user presses and holds down you get a longpress event and nothing further.

So after a long press is detected, you won't get any scrolling call-backs. You can work around this as follows. The usual way a gesture detector is used is to write your onTouchEvent method as follows:

override fun onTouchEvent(event: MotionEvent): Boolean {
return if (mDetector.onTouchEvent(event)) {
true
} else {
super.onTouchEvent(event)
}
}

You can change this to something like the following:

var isLongPress = false

override fun onTouchEvent(event: MotionEvent): Boolean {
if (mDetector.onTouchEvent(event)) {
val action = MotionEventCompat.getActionMasked(event)
if (isLongPress && action == MotionEvent.ACTION_MOVE) {
// process the drag
}
return true
}
return super.onTouchEvent(event)
}

Then in the onLongPress call-back, capture the event coordinates and set isLongPress. You can clear isLongPress in the onDown call-back. You should then ignore any call-backs to onScroll because, by definition, they will be happening without a long press.



Related Topics



Leave a reply



Submit