开发者

How to obtain the underlying view from a MotionEvent?

开发者 https://www.devze.com 2023-03-07 12:42 出处:网络
My GestureListene开发者_Python百科r class receives a MotionEvent in methods like onSingleTap() or onFling(). Is there a way to determine the underlying view from this event?

My GestureListene开发者_Python百科r 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?


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.


Give children an id and from the parent view , use parentView.findViewById(R.id.childviewid);

0

精彩评论

暂无评论...
验证码 换一张
取 消