ViewPager inside ViewPager ViewPager inside ViewPager android android

ViewPager inside ViewPager


override canScroll in the parent ViewPager:

@Overrideprotected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {   if(v != this && v instanceof ViewPager) {      return true;   }   return super.canScroll(v, checkV, dx, x, y);}


Try this:

public class CustomViewPager extends ViewPager {    private int childId;    public CustomViewPager(Context context, AttributeSet attrs) {        super(context, attrs);    }     @Override    public boolean onInterceptTouchEvent(MotionEvent event) {        if (childId > 0) {                      ViewPager pager = (ViewPager)findViewById(childId);            if (pager != null) {                           pager.requestDisallowInterceptTouchEvent(true);            }        }        return super.onInterceptTouchEvent(event);    }    public void setChildId(int id) {        this.childId = id;    }}


I searched a long time to make a ViewPager inside another ViewPager work and found the solution by "Android Noob" here. Thank you very much for that!

I wanted to share my solution, too. I added the possibility to switch the swipe management to the surrounding ViewPager once the last (most right) element in the inner ViewPager is reached. To prevent glitches, i also save the first swipe direction for the last elemen: i.e. if you swipe left first, a minimal right swipe doesnt reset the scroll state.

public class GalleryViewPager extends ViewPager {    /** the last x position */    private float   lastX;    /** if the first swipe was from left to right (->), dont listen to swipes from the right */    private boolean slidingLeft;    /** if the first swipe was from right to left (<-), dont listen to swipes from the left */    private boolean slidingRight;    public GalleryViewPager(final Context context, final AttributeSet attrs) {        super(context, attrs);    }    public GalleryViewPager(final Context context) {        super(context);    }    @Override    public boolean onTouchEvent(final MotionEvent ev) {        final int action = ev.getAction();        switch (action) {            case MotionEvent.ACTION_DOWN:                // Disallow parent ViewPager to intercept touch events.                this.getParent().requestDisallowInterceptTouchEvent(true);                // save the current x position                this.lastX = ev.getX();                break;            case MotionEvent.ACTION_UP:                // Allow parent ViewPager to intercept touch events.                this.getParent().requestDisallowInterceptTouchEvent(false);                // save the current x position                this.lastX = ev.getX();                // reset swipe actions                this.slidingLeft = false;                this.slidingRight = false;                break;            case MotionEvent.ACTION_MOVE:                /*                 * if this is the first item, scrolling from left to                 * right should navigate in the surrounding ViewPager                 */                if (this.getCurrentItem() == 0) {                    // swiping from left to right (->)?                    if (this.lastX <= ev.getX() && !this.slidingRight) {                        // make the parent touch interception active -> parent pager can swipe                        this.getParent().requestDisallowInterceptTouchEvent(false);                    } else {                        /*                         * if the first swipe was from right to left, dont listen to swipes                         * from left to right. this fixes glitches where the user first swipes                         * right, then left and the scrolling state gets reset                         */                        this.slidingRight = true;                        // save the current x position                        this.lastX = ev.getX();                        this.getParent().requestDisallowInterceptTouchEvent(true);                    }                } else                /*                 * if this is the last item, scrolling from right to                 * left should navigate in the surrounding ViewPager                 */                if (this.getCurrentItem() == this.getAdapter().getCount() - 1) {                    // swiping from right to left (<-)?                    if (this.lastX >= ev.getX() && !this.slidingLeft) {                        // make the parent touch interception active -> parent pager can swipe                        this.getParent().requestDisallowInterceptTouchEvent(false);                    } else {                        /*                         * if the first swipe was from left to right, dont listen to swipes                         * from right to left. this fixes glitches where the user first swipes                         * left, then right and the scrolling state gets reset                         */                        this.slidingLeft = true;                        // save the current x position                        this.lastX = ev.getX();                        this.getParent().requestDisallowInterceptTouchEvent(true);                    }                }                break;        }        super.onTouchEvent(ev);        return true;    }}

Hope this helps someone in the future!