My GestureListener class receives a MotionEvent in methods like onSingleTap() or onFling(). Is there a way to determine the underlying view from this event?
Background: I have a LinearLayout which contains many child views. This LinearLayout has a touch listener on it, which calls to a gesture detector. So when the user does a gesture on any child view, the LinearLayout's gesture detector receives a MotionEvent. But the problem is, because there are many children, I need to know exactly which child the user tapped on. But I can't find a method that converts a coordinate to a view. Is there a way to do this?
An ugly solution: The children are added dynamically. So I can keep all the children in a list, then when a MotionEvent comes, I can iterate through the list and see if the point is inside a child. But I don't like this idea. Is there a better way?
ACTION_DOWN : When finger or object first comes in contact with the screen. The event contains the initial starting location of a gesture. ACTION_UP : When finger or object lifts from the screen. Contains the final release location of a gesture.11-Feb-2022.
A gesture starts with a motion event with ACTION_DOWN that provides the location of the first pointer down. As each additional pointer that goes down or up, the framework will generate a motion event with ACTION_POINTER_DOWN or ACTION_POINTER_UP accordingly.
Motion Event Explanation Motion events describe movements in terms of an action code and a set of axis values. The action code specifies the state change that occurred such as a pointer going down or up. The axis values describe the position and other movement properties.
To make sure that each view correctly receives the touch events intended for it, override the onInterceptTouchEvent() method.
Are you certain you want the touch listener on the layout? Why not have each view have a touch listener?
Let's assume you have a bunch of switches that require flings to toggle. The switches control a monster. You could have each switch (your View) have a touch listener that passes the switch to the monster. Now the monster can handle each view differently.
Something like this:
brightnessSwitch.setOnTouchListener( new View.OnTouchListener() {
boolean onTouch(View v, MotionEvent event) {
monster.toggleBrightness();
return true;
});
You could even pass the MotionEvent on to the monster. (Or if you wanted a single type of TouchListeners, you could pass both the view and the event to the monster, but you lose information about which switch is which.)
Since you use an ontouchlistener on your top view group, the LinearLayout, to handle motionevents, if the return value of ontouchlistener is true, the even will not be dispatched to any other targets. So probably you need to use the ugly method. I'm current engaged in this issue and find it really annoying.
Otherwise, set ontouchlistener for each childview as needed.
If you can, use a ListView or GridView over your base layout (Linear or otherwise) and under your child views.
Then...
int pos = getGridView().pointToPosition((int) me.getX(), (int) me.getY());
View v = getGridView().getChildAt(pos);
You can also listen to the children carefully managing the boolean you return when handling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With