Android OnTouchEvent fires 3 times - android

I am trying to implement onTouchEvent on MapView to update geopoints but when I touch a screenwith the catching only ACTION_UP, it fires 3 times. How to execute my code once in this condition?
#Override
public boolean onTouchEvent(MotionEvent event, MapView mapView) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP) {
Log.e("Touch", Integer.toString(event.getAction()));
//All 3 fires has index 1 that concern to ACTION_UP
//Below will be AsyncTask call
}
return false;
}

From the method-signature, I take it that your example is from an overwritten Overlay? If so, it's documentation states:
Returns: True if the tap was handled by this overlay.
This is standard android behavior for almost every event (onTouch, onKey, etc). If the event was handled (in your case, you started your AsyncTask), you should return true, so Android knows that it has been handled.
Since you are always returning false, the framework does not know if it has been handled and dispatches the Action further down the event-handling chain. I'm not sure why it's exactly three times.
So, if you successfully handled the event, return true.

Related

tracking all touch events

Situation
I want to implement a timeout in my app. If the user did not touch the screen within 2 minutes an inactivity fragment will be shown.
What i got so far
I am tracking the activity lifecycle using a custom Application implementing Application.ActivityLifecycleCallbacks. This way i know which Activity is currently on top and can access its FragmentManager to show my inactivity Fragment on timeout. A background Thread constantly checks if the last detected touch was longer ago than 2 minutes.
Problem
I dont know how to detect every touch that happens on the activity. I tried adding a OnTouchListener to activity.getWindow().getDecorView().setOnTouchListener(), but it is only called if the decorview is touched. If for instance a Button on top of it is touched my listener isn't notified. activity.getContentScene()' returns null for me, so i can't access the rootViewGroup` like that either.
Question
How can i detect any touches that happen on a Activity or the whole Application?
override dispatch touch event in your activity
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Rect viewRect = new Rect();
view.getGlobalVisibleRect(viewRect);
//or
int x= ev.getRawX();
int y= ev.getRawY();
if(/*check bounds of your view*/){
// set your views visiblity to gone or what you want.
}
//for prevent consuming the event.
return super.dispatchTouchEvent(ev);
}

Android-dispatchTouchEvent is not catching ACTION_CANCEL

I am overriding dispatchTouchEvent() method to detect each and every touch in an activity.
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
System.out.println("android test "+event.toString());
return super.dispatchTouchEvent(event);
}
But this method is catching only ACTION_UP,ACTION_DOWN and ACTION_MOVE events,not ACTION_CANCEL event. What may be the reason for this ?
#pskink's answer is correct. i.e. ACTION_CANCEL is a system event.
"ACTION_CANCEL occurs when the parent takes possession of the motion, for example when the user has dragged enough across a list view that it will start scrolling instead of letting you press the buttons inside of i.
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent%28android.view.MotionEvent%29

Android Screen Touch Action

I am working on an android project where I need to know if user is Touch Down the screen or Touch Up the screen and I frequently need this. How can I do that?
I used on Touch Event in switch case for action Up and action down but that works for only one time. I also tried the bellow code but it gives me the the value of var(int variable) for first touch only.
my code:
int var=-1;
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if(action==MotionEvent.ACTION_DOWN)var=1;
if(action==MotionEvent.ACTION_UP)var=0;
if(action==MotionEvent.ACTION_MOVE)var=1;
return super.onTouchEvent(event);
}
I need the value of var again and again.
Since onTouchEvent is the last point of touch event traversal, it might not be called if one of the children has consumed touch event already (of if you returned false for MotionEvent.ACTION_DOWN event indicating that you are not interested in this gesture at all).
For your problem I would rather use dispatchTouchEvent() instead of onTouchEvent() and track touches there.
For more information I highly recommend getting yourself familiar with talk from Dave Smith about Android Touch System

How do I allow clicks to bubble up in onTouchEvent

I have a ViewPager that can contain two types of views. One of the view types has buttons, one of the view types does not. The buttonless view type does have to trap touches in onTouchEvent in order to pan and zoom an image. But I want to let clicks bubble to the ViewPager (that has a clickListener attached to it)
I have to return true in the view's onTouchEvent ACTION_DOWN or else it won't see future events.
I can't use onInterceptTouchEvent() in the ViewPager to capture clicks because one of the views does have buttons and those buttons need their clicks
So how can my view trap swipes, and let clicks bubble up?
proper way is probably to intercept only the events you want to intercept, by returning true in onInterceptTouchEvent only when needed.
but if you want to go with the dark side, there's a dirty alternative, that probably will lure you and you'll probably regret later: intercept all the events, then if needed pass them down.
e.g. have inside your views something like
public boolean canInterceptTouch(MotionEvent ev) {
// return true if you are interested in this touch event, e.g. it falls into
// a clickable area
}
and something that handle the touch event like
public void interceptTouch(MotionEvent ev) {
// here you react to the event
}
inside your viewpager you have
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
thien the view pager will handle the events in a dirty way like this:
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (yourView.canInterceptTouch(ev))) {
yourView.interceptTouch(ev);
return true;
} else {
return doSomethingElse();
}
}
note: although I've done something similar, with decent result, I do NOT reccomend it as a solution unless you've very simple logic in the handling of the motion events, otherwise it becomes a mess. Your future self will be happier if you spend some time now to do it properly.
EDIT: code has not been tested, just to give you an idea of what you need. Sorry for any typo.
Try using this ViewGroup.onInterceptTouchEvent(MotionEvent).This allows a ViewGroup to watch events as they are dispatched to child Views`

How can I get all of touch events in my activity even in drag mode?

I want to get x and y position of every touch point in my activity even in drag mode. When I implement onTouchEvent method of my activity, it does not get all of touch events. How can I do that?
Thanks in advance,
public class MyActivity extends Activity {
#Override
public boolean onTouchEvent(MotionEvent event) {
// my Code
return super.onTouchEvent(event);
}
}
This onTouchEvent method just rises when you touch around the activity.
Do you have any other View which handle touch events?
The documentation says:
Called when a touch screen event was not handled by any of the views
under it. This is most useful to process touch events that happen
outside of your window bounds, where there is no view to receive it.
So when you say you don't get any events when you are in drag mode, this implies that you're dragging some thing. So you already handling the events somewhere else and therefore the onTouchEvent() method won't be notified.
You can try to return false in the other TouchListener's onTouch() method so the event will bubble up further more.

Categories

Resources