I decided to post this question and answer in response to this comment to this question:
How to handle click in the child Views, and touch in the parent ViewGroups?
I will paste the comment here:
Suppose I want to override the touch events only for handling some of the children, what can I do inside this function to have it working ? I mean, for some children it would work as usual, and for some, the parent-view will decide if they will get the touch events or not.
So the question is this: How do I prevent the parent onTouchEvent()
from overriding some child elements' onTouchEvent()
, while having it override those of other children?
onTouchEvents()
for nested view groups can be managed by theboolean
onInterceptTouchEvent.The default value for the
OnInterceptTouchEvent
is false.The parent's
onTouchEvent
is received before the child's. If theOnInterceptTouchEvent
returns false, it sends the motion event down the chain to the child'sOnTouchEvent
handler. If it returns true the parent's will handle the touch event.However there may be instances when we want some child elements to manage
OnTouchEvent
s and some to be managed by the parent view (or possibly the parent of the parent).This can be managed in more than one way.
OnInterceptTouchEvent
is by implementing the requestDisallowInterceptTouchEvent.This prevents any of the parent views from managing the
OnTouchEvent
for this element, if the element has event handlers enabled.OnInterceptTouchEvent
is false, the child element'sOnTouchEvent
will be evaluated. If you have a methods within the child elements handling the various touch events, any related event handlers that are disabled will return the OnTouchEvent to the parent.This answer:
https://stackoverflow.com/a/13540006/3956566 gives a good visualisation of how the propagation of touch events passes through:
parent -> child|parent -> child|parent -> child views.
OnInterceptTouchEvent
for the parent.This example taken from Managing Touch Events in a ViewGroup and demonstrates how to intercept the child's
OnTouchEvent
when the user is scrolling.4a.
Edit: To answer comments.
This is some code from the same link showing how to create the parameters of the rectangle around your element:
4b.
Lets revamp the issue.
You happen to have a ViewGroup with a bunch of children. You want to intercept the touch event for everything withing this ViewGroup with a minor exception of some children.
I have been looking for an answer for the same question for quite a while. Did not manage to find anything reasonable and thus came up on my own with the following solution.
The following code snippet provides an overview of the ViewGroup's relevant code that intercepts all touches with the exception of the ones coming from views that happen to have a special tag set (You should set it elsewhere in your code).