#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// why this code can be executed.
getParent().requestDisallowInterceptTouchEvent(true);
return super.dispatchTouchEvent(ev);
}
getParent().requestDisallowInterceptTouchEvent(true) tell parent don't intercept touch event. but if parent already intercept touch event, the event can't pass to child view, and child view how to execute getParent().requestDisallowInterceptTouchEvent(true) ?
I will give you a simple example to why to use.
getParent().requestDisallowInterceptTouchEvent()
If i have a ViewPager and Each page is a ScrollableView(Horizontal Scrolling).Now there is a condition to scroll and changing the page of ViewPager using swipe.
i.e View will get confused to scroll or swipe!!!
So this condition need's to be checked in the child View (i.e ScrollableView),once if condition is matched use scrolling and set below
getParent().requestDisallowInterceptTouchEvent(true)
As you don't want any parent View (i.e ViewPager) to interfere in child event.So Basically what the framework will do is won't call onintercepttouchevent() of any of the parent view Reference
But if you want ViewPager to get Event's set below
getParent().requestDisallowInterceptTouchEvent(false)
NOTE: By default on each ACTION_DOWN call of touch Event's requestDisallowInterceptTouchEvent is set to false
Related
My fragment view implements a touch listener to listen to various gestures but my horizontally fashioned recyclerview consumes any gesture performed over it.
Basically I want to listen to vertical swipe when performed over recyclerview but I never receive callback in fragment view's gesture detector.
I was able to get a workaround for it. I had to subclass ViewGroup and override onInterceptTouchEvent and handle things using MotionEvent.{action_type}. Then I replaced the fragment view's parent view group with this custom view group inside xml layout.
So in nutshell, if I detect it as a vertical swipe I return true in my onInterceptTouchEvent otherwise false. If its false, the touch event is passed onto the child views for handling. Works perfect.
I have a listview inside a RelativeLayout. I want any clicks on the listview to call the Relativelayout's onClick listener. How can the listview pass it's click events to the parent view.
I tried this not working.
listView.setOnTouchListener(new OnTouchListener() {
// Setting on Touch Listener for handling the touch inside
// ScrollView
#Override
public boolean onTouch(View v, MotionEvent event) {
// Disallow the touch request for parent scroll on touch of
// child view
listView.requestDisallowInterceptTouchEvent(false);
return false;
}
});
I think you need to use one of those methods in order to be able to intercept the event before it gets sent to the appropriate components:
Activity.dispatchTouchEvent(MotionEvent) - This allows your Activity to intercept all touch events before they are dispatched to the window.
ViewGroup.onInterceptTouchEvent(MotionEvent) - This allows a ViewGroup to watch events as they are dispatched to child Views.
ViewParent.requestDisallowInterceptTouchEvent(boolean) - Call this upon a parent View to indicate that it should not intercept touch events with onInterceptTouchEvent(MotionEvent).'
for reference please check here EventHandlers
Can use in XML:
android:focusable="false"
In java code use:
v.setClickable(false)
I have a custom linearlayout in which I have two gridviews.
I want to have multitouch on the complete linearlayout, ie, first touch can be in one gridview and second touch can be in another gridview and the linear layout should be able to get multitouch events for this (ACTION_DOWN and ACTION_POINTER_DOWN). I am able to get this by overriding onInterceptTouchEvent in my custom layout.
Now I also want the gridview to scroll independently if required. Although gridview is a scrollable view, it is not able to do so, because I have intercepted the 'down' event. I see that when I try to scroll two events are generated : 'ACTION_DOWN' and 'ACTION_MOVE'.
Since I need ACTION_DOWN for multitouch use case I want it to be sent to linearlayout as well.
Is there a possibility to send the ACTION_DOWN event to both the linearlayout as well as my child view which is gridView in this case?
Need help.
You don't have to intercept ACTION_DOWN just to monitor that it flowed through your container view. In other words, you can override onInterceptTouchEvent() to monitor the touch events before they are passed to the appropriate child view by the framework, but as long as you don't screw with the return value it won't actually steal subsequent touch events from the grid elements. For example:
public boolean onInterceptTouchEvent (MotionEvent ev)
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
//Touchdown!
}
//Don't modify this and touch interaction will happen normally
return super.onInterceptTouchEvent(ev);
}
This allows you to see the event without taking it away from the child element(s).
I am intending to transfer a touch event from a parent view to its child. I tried some constructions but so far I have not succeeded to assign touch handling to another view, but only delegating touch handling from parent to child views, which is not quite the same.
This is what I like to achieve:
The green dot is a Touch Down Event on the parent, then I am dragging towards another view, which is than picked up on the blue spot (firing Touch-Down on the child view) and from this point the parent view is not involved anymore, like I would have touched the child in the first place.
I could delegate the touch event by extending the parents onTouchEvent method, and then calling child.dispatchTouchEvent(), when entering the childs view-bounds, but I would like to avoid the parents involvement.
From the View.OnTouchListener documentation, the return of an OnTouch() is:
Returns
True if the listener has consumed the event, false otherwise.
Basically, if you want the parent to react to the onTouchListener, return false. If you want it to not react, return true.
I tried to understand how Android handle touch event and got a little bit confused. From what I understand touch event are send to the root view and pass down to the children.
I have a FrameLayout that is a container for Fragment.
First fragment view is a ScrollView, second one is some kind of Gallery (HorizontalListView) and the last one is also FrameLayout. Only one fragment in the layout each time.
What I want to do is to identify user swipes on the screen, for the app use. I want to count the swipes and do something after some number of swipes.
I tried to put a OnTouchListener on the top FrameLayout but it doesn't get called when the child is the ScrollView or the Gallery. I tried to return false and also true in the end of onTouch, but I get same result - it's never being called.
How can I do it?
I just want to "transparently" handle the touch events and passing them on like I didn't even touch them.
My understanding is that it actually goes the other direction. The Child views get their event triggered first (sort of). The root view get's it's dispatchTouchEvent() called, which propagates the event down to the children's onTouchEvent(), and then, depending on whether they return true or false, the parent's onTouchEvent() is called.
The normal solution for intercepting things like this is to override dispatchTouchEvent(MotionEvent ev) in one's activity like so:
#Override
public boolean dispatchTouchEvent (MotionEvent ev) {
// Do your calcluations
return super.dispatchTouchEvent(ev);
}
The documentation for this one is here. Note that you can also override that method in any ViewGroup (such as a FrameLayout, etc)