How to capture onTouch events on two overlapping views?

Markup

! * A container is a relative layout containing two custom views: OuterView1 and InnerView2 * Outer View1 is a custom view that matches the size of the parents (full screen) * Inside view2 is also a custom view overlaid on top of OuterView1 that overlaps it.

  • A container is a relative layout containing two custom views: OuterView1 and InnerView2
  • Outer View1 is a custom view corresponding to the size of the parents (full screen).
  • Interior View2 is also a custom view located on top of OuterView1 that overlaps it.

In OuterView1 and InnerView2, I want to capture these touch events on SingleTapConfirmed () and onFling (). The area where both OuterView1 and InnerView2 overlap, I want the control to be passed to the touch event methods of both views.

I tried this:

Container class

@Override public boolean onInterceptTouchEvent(MotionEvent ev) { outerView1.onTouchEvent(ev); innerView2.onTouchEvent(ev); return false; } 

Class OuterView1

  @Override public boolean onTouchEvent(MotionEvent event) { gesture.onTouchEvent(event); return true; } 

gesture is an example of a GestureDetector.SimpleOnGestureListener with log statements for the onDown (), onFling (), and onSingleTapConfirmed () methods

Class InnerView2

  @Override public boolean onTouchEvent(MotionEvent event) { gesture.onTouchEvent(event); return true; } 

gesture is an example of a GestureDetector.SimpleOnGestureListener with log statements for the onDown (), onFling (), and onSingleTapConfirmed () methods

With this approach, I consistently get a callback in the onDown () methods of both views. But I do not see consistent behavior in the onSingleTapConfirmed () and onFling () methods

When I tapped the red circle (in the screenshot) three times, and I got three different behaviors

  • First try (desired behavior)

     10-14 09:03:14.155: I/OuterView1(27776): OuterView1.onDown() 10-14 09:03:14.155: I/InnerView2(27776): InnerView2.onDown() 10-14 09:03:14.155: W/GestureDetector(27776): [pen gesture] isConsideredDoubleTap - timeout 10-14 09:03:14.155: I/InnerView2(27776): InnerView2.onDown() 10-14 09:03:14.460: I/OuterView1(27776): OuterView1.onSingleTapConfirmed() 10-14 09:03:14.460: I/InnerView2(27776): InnerView2.onSingleTapConfirmed() 
  • Second attempt (only one view gets onSingleTapConfirmed ())

     10-14 09:04:11.615: I/OuterView1(27776): OuterView1.onDown() 10-14 09:04:11.615: I/InnerView2(27776): InnerView2.onDown() 10-14 09:04:11.615: W/GestureDetector(27776): [pen gesture] isConsideredDoubleTap - timeout 10-14 09:04:11.615: I/InnerView2(27776): InnerView2.onDown() 10-14 09:04:11.915: I/OuterView1(27776): OuterView1.onSingleTapConfirmed() 
  • Third attempt (one view gets onFling () and the other gets onSingleTapConfirmed ())

     10-14 09:04:04.180: I/OuterView1(27776): OuterView1.onDown() 10-14 09:04:04.180: I/InnerView2(27776): InnerView2.onDown() 10-14 09:04:04.180: W/GestureDetector(27776): [pen gesture] isConsideredDoubleTap - timeout 10-14 09:04:04.180: I/InnerView2(27776): InnerView2.onDown() 10-14 09:04:04.255: I/InnerView2(27776): InnerView2.onFling() 10-14 09:04:04.480: I/OuterView1(27776): OuterView1.onSingleTapConfirmed() 

Could you help me capture touch events for both OuterView1 and InnerView2?

+7
android touch-event overlapping
source share
1 answer

Thus, in the case of overlapping views, touch events are sent from the uppermost child to one at the back, then another after the second child, and so on. However, if the uppermost child was to use a touch event (i.e., Process it when it is received), then the views under this view will not receive touch events.

If onTouchEvent returns true, it tells the view manager that it handled the touch and does not want the event to be dispatched to other views. If you want the view under this view to also get a touch, you want to return "false" from onTouchEvent for the first view, in your case "Innerview".

Also, in your code, I noticed that you programmatically send touch events to 2 views from the container class. This causes InnerView to get a touch even when OuterView is ONLY used. If you want this functionality, then everything is in order. If you want InnerView to receive events only when it has been touched, you do not want the container class to call onTouchEvent explicitly in these two views. The hierarchy of views will do this for you.

About getting onFling or onSingleTapConfirmed on BOTH views - (if you want touch events to go to views, and also, you return "false" from onTouchEvent for InnerView), InnerView already passed the event a look behind it, so it does not reach the end gestures to understand what just happened, and similarly for onSingleTapConfirmed. If you want to receive them, you may have to automatically send touch events at the end of gestures, as OuterView has detected. Meaning, if OuterView received fling gestures, then this was also for InnerView, and therefore programmatically make this gesture for InnerView. This is quite complicated, and dispatching calls back in the hierarchy is not an ordinary thing.

I hope I didn’t confuse you. Feel free to ask if I’m clear, and I will try again.

This will be useful: Handling TouchEvents in a ViewGroup

+9
source share

All Articles