OnLongPress only touch is not moving - android

I got a view in android which I want to accept onLongPress actions.
I've got a OnTouch method which handles stuff when moving around across the screen. But when long pressing without moving the finger, the OnLongPress method should be called.
My effort so far is that I got the onTouch events working. But now, when swiping around the view, the onLongPress method gets called, because logically, I am long pressing the screen.
I just want the onLongPress work when the finger is held still on the screen without moving, is there a way how to achieve this?

You should cancel the long press. From the documentation:
public void cancelLongPress()
Cancels a pending long press. Your subclass can
use this if you want the context menu to come up if the user presses
and holds at the same place, but you don't want it to come up if they
press and then move around enough to cause scrolling.

How about something like this:
#Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downTime = Calendar.getInstance().getTimeInMillis();
return true;
case MotionEvent.ACTION_UP:
upX = event.getX();
upTime = Calendar.getInstance().getTimeInMillis();
float deltaX = downX - upX;
float deltaTime = upTime - downTime;
if((deltaX < UNACCEPTABLE_MOVE_DISTANCE) && (deltaTime > MINIMUM_TIME))
//REPORT LONG PRESS WITH INTERFACE
else
//REPORT SOMETHING ELSE
return true;
default:
return true;
}
}

Related

How do I finish tracking ACTION_MOVE in android?

As I know, if my onTouch method returns false, after the initial ACTION_DOWN case it does not start tracking the movement, and if I return true, it does. But I have some cases when I need to stop tracking the movement from some moment. How do I achieve this? I tried to returning false when my condition holds, but it continues to run into that case. How to cancel or stop the motion event?
Here is the code I have for my drag and drop application, and when the X is less than 100, I just want to stop dragging. How can I achieve this?
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
imageTouchX = (int) event.getRawX() - (int) img.getX();
imageTouchY = (int) event.getRawY() - (int) img.getY();
break;
case MotionEvent.ACTION_MOVE:
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
img.setX(x_cord - imageTouchX);
img.setY(y_cord - imageTouchY);
if(img.getX() < 100){
return false;
}
break;
default:
break;
}
return true;
}
Thanks in advance.
what if the img goes under the x location of 100 and then comes back ?
one way to do it is to disable the touchevent all together, but then how you'll get the next touchevents ? unless it's going to be another view that will receive the touch event, anyhow, if you stop the touch events you won't receive any touch events again, and if this is what you wish to get, just disable the touchevent for this view, you can enable it again when you choose, good luck ! :)

MotionEvent.ACTION_DOWN in Android is too sensitive. This event is received even if the screen is simply touched for a moment

I have a layout(A table layout). Whenever the user performs a "down" gesture, a specific function needs to be called. However,the ontouchlistener captures the event immediately instead of waiting until the user performs a proper "pull down" gesture.
My code is :
homePageTableLayout.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
if ((event.getAction() == MotionEvent.ACTION_DOWN)) {
startSyncData();
}
return true;
}
});
Currently, what's happening is that the startSyncData() function gets called immediately.
The end result should be somewhat similar to the commonly used "pulltorefresh" library for android but in this usecase, I don't have to update the view. I just have to post some data to the server.
I can't use the "pulltorefresh" library because it does not support "pulling" a tablelayout. I tried putting the tablelayout inside a scrollview but that only spoiled the UI.
You can try doing it in ACTION_MOVE or ACTION_UP - if you need it to be done exclusively on swipe down gesture, this should help, introduce four global floats: x, y, x1, y1, then in ACTION_DOWN:
x = event.getX();
y = event.getY();
ACTION_MOVE or ACTION_UP:
x1 = event.getX();
y1 = event.getY();
and then in ACTION_UP:
if (y1 > y) { //pointer moved down (y = 0 is at the top of the screen)
startSyncData();
}
Its not that easy. It works properly since you are catching MotionEvent.ACTION_DOWN. It doesn't mean a gesture like swipe down it means that user touched the screen (finger down, the touch or gesture just started). Now you need to catch MotionEvent.ACTION_UP (finger up, gesture or touch ends here) and decide if there was a gesture you need. http://developer.android.com/training/gestures/detector.html
http://developer.android.com/training/gestures/index.html
MotionEvent.ACTION_MOVE repeatedly gets called. So if you want startSyncData() to run after moving a certain distance, calculate how much you want the user to move before running the method.
The key is that ACTION_DOWN is not a downwards movement on the screen, but it means the user pressed down onto the screen.
homePageTableLayout.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
if ((event.getAction() == MotionEvent.ACTION_DOWN)) {
startFlg = 1;
} else if ((event.getAction() == MotionEvent.ACTION_MOVE)) {
if (startFlg==1){
// Calculate distance moved by using event.getRawX() and event.getRawX() and THEN run your method
startSyncData();
}
}
return true;
}
});

Detect swipe on ListView

How do i detect swipe up and down on a listView. I have tried the following methods
Using onSimpleGestureListener,onFling() works for fling( i.e when i leave the screen after swipe). But it doesnt get called on swipe( finger not lifted from screen finally).
2.In onScroll() of onSimpleGestureListener, distanceY is not helpful for detecting up and down swipe. It works fine for fling detection, but fluctuates its values from negative to positive in a particular swipe.
Using onTouchListener
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
before = event.getY();
break;
case MotionEvent.ACTION_MOVE:
now = event.getY();
if (now < before) {
upSwipe()
} else if (now > before) {
downSwipe();
}
}
return false;
}
When i swipe up, variable now sometimes becomes greater than variable previous and sometimes small. So both upSwipe() and downSwipe() is called.
I am banging my head for hours. Not able to sole this.
Have you tried to return true instead of returning false.
Based on the Detecting Common Gestures documentation.
"Beware of creating a listener that returns false for the ACTION_DOWN event. If you do this, the listener will not be called for the subsequent ACTION_MOVE and ACTION_UP string of events. This is because ACTION_DOWN is the starting point for all touch events."

Android Listener to detect when the screen is being pressed

I have a view in my Android app that should be updated constantly when the screen is being pressed. Most listeners I found only invalidate the view once when the user touches the screen for the first time, or when the user removes his hand from the screen.
Is there such a thing as a listener that is constantly triggered as long as the screen is touched ? Or is there any other way to do this ? I know, that sounds like something really simple, but I haven't found a way to do it.
Override onTouch() and set a flag in ACTION_DOWN. As long as ACTION_UP isn't called after that, the user is touching the screen.
boolean pressed = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
//int action = event.getAction();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
pressed = true;
break;
case MotionEvent.ACTION_MOVE:
//User is moving around on the screen
break;
case MotionEvent.ACTION_UP:
pressed = false;
break;
}
return pressed;
}

"Live" get(x) and get(Y) values (for MotionEvents) ****UPDATE****

I was wondering how to get accurate, live get(x) and get(y) values for a MotionEvent? What is happening is that when I touch a specific area on the screen, I tell an action to happen.
The problem is that once I touch the screen and take my finger off, it still thinks my finger is at the same location (since that was the last location I touched). So when I have more than one Down event (for multitouch) it throws everything off. Is there a way to reset the X and Y values so when I let off the screen, they go back to 0 or null (or whatever)? Thanks
What you are describing isn't a problem. You the programmer are responsible for keeping track of the touch locations and what they mean. If you care about motion you need to keep track of the previous touch and the current touch each time a touch occurs. I find something like this works great:
public int x=-1,y=-1,prevX=-1, prevY=-1;
public boolean onTouch(View v, MotionEvent event)
{
prevX = x;
prevY = y;
int x = (int)event.getX();
int y = (int)event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
// there is no prev touch
prevX = -1;
prevY = -1;
// touch down code
break;
case MotionEvent.ACTION_MOVE:
// touch move code
break;
case MotionEvent.ACTION_UP:
// touch up code
break;
}
return true;
}
Just catch the MotionEvent.ACTION_UP or ACTION_MOVE event, depending on when the action needs to happen (since you want it live, you should use the ACTION_MOVE event). You should handle setting external variables when ACTION_DOWN occurs, and handle the results on ACTION_MOVE or ACTION_UP.

Categories

Resources