I know there are several answers which describe how to lock a ViewPager.
But I want that my ViewPager is able to scroll only if the touch doesn't occour on a specific child.
So how can I "filter" out which child views are touched?
example code of how I want to lock my ViewPager:
for (Integer resource:mResources) {
if(resource.intValue()==view.getId()){
touchTriggeredOnView(view.getId());
}
}
The reason why I want to do this is, that I have a custom view which needs to detect fling gestures.
This custom view is a child of a Fragment and the Fragment is a child of the ViewPager.
So: ViewPager->Fragment->CustomView.
I'm able to detect the DOWN but not the FLING event inside my CustomView.
I think that the ViewPager captures the FLING event --> bad thing.
I hope that my question is clear enough.
onTouch and gesture listeners in Android have boolean return values which indicate whether event (touch, fling, click) is consumed or not.
ViewPager probably consumes "Fling" event, however you could override onTouch, gesture listener in ViewPager and return false - thus not consuming touch event and passing it to your custom view.
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 extended a FrameLayout and overriden the onInterceptTouchEvent() and onTouchEvent(). This custom Framelayout will be the root layout of my ListView rows.
My requirement is that, if I tap on a row in the ListView, the onItemClickListener should be called, if I scroll (up/down) the list scrolls as usual. However if I scroll (left/right) or swipe (left/right), the custom FrameLayout should take some action based upon which row I perform the action on.
My idea was that, I would override onInterceptTouchEvent, monitor the events and if I see that ACTION_MOVE has been called enough to make it a scroll/swipe then I take control and do the task. If it's a tap or some other gesture then let the default flow occur.
The problem I face now is that if my framelayout does not contain any touchable child, then I receive no calls post ACTION_DOWN. And if I receive the ACTION_DOWN in my onTouchEvent() so as to analyze the kind of gesture, then I have no control left to let the default flow occur if I calculate and find that the action was actually just a tap/vertical scroll.
Is there some way in which a child can get hold of the events (ACTION_DOWN and ACTION_MOVE) and if a condition satisfies then perform an action or else let the parent handle these same events?
Is there some other approach that I can take to satisfy this requirement?
I am having a gesture listener attached to a view and I have onSingleTap Event handled.
It handles it properly if I tap anywhere in the view. But say if the View is having any subview and if I am tapping the subview the event does not get triggered.
Is there a way to pass this touch from child to parent? And also the children contains BUTTONS. so if the press is on a child button it should not pass the touch to parent. Otherwise it must pass it to parent. Anyway to achieve this?
You can override the Activity's dispatchTouchEvent(MotionEvent) in order to handle the dispatching yourself.
A good handling would be to first check if it triggers the gesture in your view and if not just call super.dispatchTouchEvent(MotionEvent);
The one thing you have to care about while doing this is to keep the gestures coherent with the rest of the platform.
I'm using a ViewPager and in one of my pages I have a View with overriden onTouchEvent() method.
Now when user moves his finger on a screen, onTouchEvent() of my View is being called, but also ViewPager is moving a page to left or right. I'd like to prevent somehow ViewPager from calling it's onTouchEvent() method IF a user is touching my View's area. Is it possible?
ViewPager will by default intercept all touch events. In fact, if you put anything inside anything else that scrolls, the container will intercept the touch event. You can override this behavior in certain cases. There is a similar problem with a solution here that might help you:
ViewPager intercepts all x-axis onTouch events. How to disable?
The problem is the the scrolling will intercept with touch event has set to the parent layout.
Can I keep the onTouch event with the scroll in ScrollView ?
This is a very tricky part. There is an overriden method from Activity which is: public boolean onTouchEvent(MotionEvent event)
This is the general method that interprets all the touch events from the whole screen. And you could say, "ok, I can implement this and I am good to go..". And here comes the difficult part on how android works.
As you know every View has its own onTouchEvent() method that you could implement in order to add some custom implementation. So which method will listen? The ScrollView or the Activity? It appears that these touch events go from the "inside" elements to the "outside" elements. I mean parent-child relations.
Another thing to take into account is that the onTouchEvent method returns a boolean. This boolean parameter determines whether the touch event should go one level up or it is handled by the current View. Meaning that if you have a CustomViewA that implements the onTouchEvent() and CustomViewB implementing its own touch event, and the A is a child in B then the touch event would go through A first and if it is not handled it would go to B.
So basically yes it could be done. It depends on what touch event you wanted to do.
So in our case, the ScrollView returns true when the touch events are a horizontal. The activity's touch event will be handled only if the ScrollView touch event is not handled by itself then you are fine. Otherwise you have to override and implement the on touch event of scroll view and in some cases you have to return false so as for the whole layout to implement it. Good luck with the last part. I started to implement a fling effect but came up with some difficulties so I have implemented a 2 finger move with scroll view in it and it works like a charm.
This is about a week of research and experimenting and it is an overview of what I came up with. if you find anything else please let me know. Hope it helped.