34

Scope

There is a viewpager of two fragments. One of those fragments has a layout witch listens to onTouch changes at X-axis.

Problem

Layout doesn't get almost all Action.Move events when touching and sliding along X-axis. It seems that viewpager has a onInterceptTouchEvent which returns true.

Question

Is it real to override viewpager's behavior to make it and my layout work together? So the perfect situation is layout intercepts all onTouch events on it and viewpager manages the rest of onTouch events. Thanks!

Community
  • 1
  • 1
Oleksii Malovanyi
  • 6,780
  • 6
  • 24
  • 27
  • I used list in one of Fragment view which is handle by ViewPager...and I also facing same issue...if start to swipe..it start to shift in x-direction slightly....I tried @neutrino as well...but problem remain same...any suggestion/idea? – CoDe Mar 02 '14 at 20:10
  • additionally I am using Listview in Fragment...so I have to ask requestDisallowInterceptTouchEvent true for list view also...but it hectic now...as it intercepting click event for list event...any suggestion/update? – CoDe Mar 02 '14 at 20:41
  • something interesting here also http://stackoverflow.com/a/7814054/2624806 – CoDe Mar 03 '14 at 05:26

4 Answers4

43

You are right, I believe every scrolling container intercepts touch events, but you can prevent it. You can put a touch listener on your layout:

public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_MOVE: 
        pager.requestDisallowInterceptTouchEvent(true);
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
        pager.requestDisallowInterceptTouchEvent(false);
        break;
    }
}
alex.zherdev
  • 23,914
  • 8
  • 62
  • 56
  • Thanks! I should be more patient and careful with android documentation. – Oleksii Malovanyi Nov 14 '11 at 14:47
  • 2
    Will this only work in onTouch ? I tried this in onScale but it is still intercepting my touch. – devanshu_kaushik Nov 30 '11 at 10:53
  • 5
    Two notes: 1. You don't have to keep reference to the pager - calling `getParent().request...` is enough, the parent will propagate the request. It makes it more flexible to use in a custom view. 2. At first I thought that calling `request...` for the view once at the initiation is enough. It appears that it must be called for EVERY touch event. This is why you have to do it `onTouch()` @dev_android – Michał Klimczak Jul 05 '13 at 13:16
  • 1
    This prevented the tab switching when the user swiped horizontally on my image. Awesome ! – Someone Somewhere Nov 13 '13 at 05:44
  • If you update the content of the ViewPager by calling notifyDataSetChanged on the pager adapter WHILE swiping over the layout that listens to the onTouch event, it doesn't work anymore! Then the ViewPager flips. Anyone knows a solution to that? – DominicM Jan 27 '14 at 22:42
  • Great answer, it solved my problems with the ViewPager intercepting my scroll down events. – reixa Nov 02 '17 at 08:59
19

Similar situation (but not using a ViewPager), putting this in the view that needed the touch event worked for me. Add checks for MotionEvents other than ACTION_MOVE if applicable to your use case.

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_MOVE) {
        this.getParent().requestDisallowInterceptTouchEvent(true);
        return true;
    } else {
        return super.onTouchEvent(event);
    }
}
Kuffs
  • 35,581
  • 10
  • 79
  • 92
  • This is the correct solution, however I would like to note that this event WILL still be handled by the ViewPager (or any intermediate ViewGroups) if you do not return true. If you return false, the event is unhandled and will propagate back up to the ViewPager. – nacitar sevaht Mar 29 '12 at 21:01
1

neutrino was right!

getParent().requestDisallowInterceptTouchEvent(true);

once the viewpager access the touchEvent Intercept,the child view in it can got the event. enter image description here


I use a FrameLayout in viewpager to got the DrawerLayout Effect(I need it not match the height of screen,so I can't use drawerlayout or navigation drawer).
It really helps!

Jaiprakash Soni
  • 4,100
  • 5
  • 36
  • 67
GeekLei
  • 991
  • 7
  • 8
-1

I had a similar problem.

In my case I was setting a OnTouchListener on ViewPager but it wasn't receiving touch events when the children that received the touch had onClick set.

What I did was extend the ViewPager class and call my click listener inside the method onInterceptTouchEvent(boolean) and it worked fine. Just be careful not to intercept wrong events.

tbraun
  • 2,636
  • 31
  • 26