I know there are questions like this already with answers, but I'm not having any luck with anything, so this is a last resort.
I have a LinearLayout containing a ScrollView. I want the LinearLayout to respond to click, tap, touch whatever you want to call it, but the ScrollView is interfering, so the LinearLayout's click handler is never invoked. I don't mind sub-classing ScrollView and overriding onTouchEvent (but I don't understand what to put into it), but an alternative solution is fine too. I've tried using requestDisallowInterceptTouch(true) on the LinearLayout, the ScrollView and the first child of the ScrollView, but it's not working (TBH, the javadoc for that method confuses me).
If I use this override in my custom scrollview:
@Override
public boolean onTouchEvent(MotionEvent event) {
return false;
}
...the LinearLayout does respond to taps, but scrolling is completely disabled, and every type of touch gesture results in the LinearLayout click handler being invoked. So, what do I need to do to let scrolling movements be handled as they normally would and also get the ScrollView to ignore clicks/taps?
For what it's worth, the XML looks something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/my_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
.../>
<com.package.MyScrollView
android:id="@+id/my_scroller"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbars="vertical">
...
...
Under normal circumstances, the TextView area will detect the click registered with the LinearLayout, but the ScrollView will not.
First of all, requestDisallowInterceptTouch(true)
unfortunately does completely the opposite of what you want to achieve. It forces all parent ViewGroup
s including the one on which you call the method to disregard events passed to them in onInterceptTouchEvent()
.
Normally, that is without setting setting this flag to true
, new touch events are first passed from root to leaf all the way down the view tree which allows parents (i.e. ViewGroups
) to intercept those events by returning true
which redirects all following events of the same gesture to this ViewGroup
s onTouchEvent()
method. After a view tree leaf is reached (assuming that no one has returned true
in onInterceptTouchEvent()
) the event bubbles back to the root via the onTouchEvent()
method. Again returning true
means that the event is consumed in the view doing so and all further events will be directly passed to your onTouchEvent()
method rather than traversing through the whole view tree. So the difference between onInterceptTouch()
and onTouch()
is the direction of traversal through the view tree - reading all that I'm not really sure if it is more comprehensible than the javadoc.^^
Nevertheless, to put a long story short: requestDisallowInterceptTouchEvent(true)
is no solution here.
That's for the prolog. Still here? Lucky you - because there is a (somewhat ugly) workaround for the situation you have observed: put a OnClickListener
on the child of the ScrollView
and let it performClick()
on your LinearLayout
that should do the trick. This will keep the ScrollView
in a working state (unlike your attempt to override onTouch
), but passes all click events (and only those) to the outer LinearLayout
.
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