Detect Touch Press VS Long Press VS Movement

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.

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 distinguish between move and click in onTouchEvent()?

Here's another solution that is very simple and doesn't require you to worry about the finger being moved. If you are basing a click as simply the distance moved then how can you differentiate a click and a long click.

You could put more smarts into this and include the distance moved, but i'm yet to come across an instance when the distance a user can move in 200 milliseconds should constitute a move as opposed to a click.

setOnTouchListener(new OnTouchListener() {
private static final int MAX_CLICK_DURATION = 200;
private long startClickTime;

@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
startClickTime = Calendar.getInstance().getTimeInMillis();
break;
}
case MotionEvent.ACTION_UP: {
long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
if(clickDuration < MAX_CLICK_DURATION) {
//click event has occurred
}
}
}
return true;
}
});

How to probably handle different touch events, especially taps and long press on screen?

So, I was able to perfectly handle touch events by implementing the GestureDetector.OnGestureListener methods in conjunction with the onTouchEvent() methods.

    private GestureDetectorCompat mDetector;
boolean mIsScrolling;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview);

// Instantiate the gesture detector with the
// application context and an implementation of
// GestureDetector.OnGestureListener
mDetector = new GestureDetectorCompat(this,this);

//set TouchListener on previewLayout
previewLayout.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {

if (mDetector.onTouchEvent(event)) {
return true;
}

if(event.getAction() == MotionEvent.ACTION_UP) { //when user left his finger up
if(mIsScrolling) { //if it was a scroll action
handleScrollFinished();
mIsScrolling = false; //set mIsScrolling back to false

}
}

return PreviewActivity.super.onTouchEvent(event);
}

});
}

.

@Override
public boolean onDown(MotionEvent event) {
//Do stuff
return true;
}

@Override
public boolean onSingleTapUp(MotionEvent event) {
//So stuff
return true;
}

@Override
public void onLongPress(MotionEvent event) {
//Do stuff
}

@Override
public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
float distanceY) {
mIsScrolling = true;

//Do stuff
return true;
}

private void handleScrollFinished() {

//Do stuff

}

@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
return false; //it has to return false, or I will have to write unnecessary extra code
}

@Override
public void onShowPress(MotionEvent event) {
}

Things that helped me through:

  • Detect common gestures

  • How to detect when a scroll has ended

Simulate Long press by Touch events

I have implemented a Touch screen long click finally , thx all:

textView.setOnTouchListener(new View.OnTouchListener() {

private static final int MIN_CLICK_DURATION = 1000;
private long startClickTime;

@Override
public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {
case MotionEvent.ACTION_UP:
longClickActive = false;
break;
case MotionEvent.ACTION_DOWN:
if (longClickActive == false) {
longClickActive = true;
startClickTime = Calendar.getInstance().getTimeInMillis();
}
break;
case MotionEvent.ACTION_MOVE:
if (longClickActive == true) {
long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
if (clickDuration >= MIN_CLICK_DURATION) {
Toast.makeText(MainActivity.this, "LONG PRESSED!",Toast.LENGTH_SHORT).show();
longClickActive = false;
}
}
break;
}
return true;
}
});

in which private boolean longClickActive = false; is a class variable.

Javascript: Detecting a long press

You could beautify this through using some curried arrow functions:

const listen = (el, name) => handler => el.addEventListener(name, handler);

const since = (onStart, onEnd) => {
let last = 0;
onStart(() => last = Date.now());
onEnd(() => last = 0);
return time => Date.now() - last < time;
};

So you can just do:

const longPress = since(
listen(listItem, "touchstart"),
listen(listItem, "touchend")
);

listen(listItem, "touchmove")(evt => {
if(longPress(100)) {
//...
}
});

How to detect touch when you are moving over a button

If we set Click or Touch listener to Button which is 50dp width at center, then the listener will get callback only if the user click/touch initiating from button.

While in your problem case, You are initiating click/touch from outside and coming to button.

So, button listener will not get callback from Android Framework

For your requirement to work, we need to add some logic, i have tried to add it here :

activity_main.xml :

<RelativeLayout android:id="@+id/parentLayout" ... >

<Button android:id="@+id/buttonCenter ... />

</RelativeLayout>

MainActivity.java :

// apply touch listener to parentLayout
button = (Button) findViewById(R.id.buttonCenter);
parent = (RelativeLayout) findViewById(R.id.parentLayout);

parent.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {

Log.d("tag","in onTouch...");
checkTouch(event);

return true;
}
});

// check if touch entered button area

// save button left, right, top and bottom edge

// update : This is API i found on google documentation
float[] params;
button.getLocationOnScreen(params);

public void checkTouch(MotionEvent event) {
x = event.getX();
y = event.getY();

if(x >= param[0] && x <= (param[0]+button.getWidth())) {
if(y >= param[1] && y <= (param[1]+button.getHeight())) {
Log.d("tag","this touch is in button area");
// do what you want to do when touch/click comes in button area
}
}
}

How to detect a long touch pressure with javascript for android and iphone?

The problem with using Touch End to detect the long touch is it won't work if you want the event to fire after a certain period of time. It is better to use a timer on touch start and clear the event timer on touch end. The following pattern can be used:

var onlongtouch; 
var timer;
var touchduration = 500; //length of time we want the user to touch before we do something

touchstart() {
timer = setTimeout(onlongtouch, touchduration);
}

touchend() {

//stops short touches from firing the event
if (timer)
clearTimeout(timer); // clearTimeout, not cleartimeout..
}

onlongtouch = function() { //do something };


Related Topics



Leave a reply



Submit