Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - ViewPager scrolling resets

I'm using a ViewPager in my app that houses a horizontal layout of images to implement a Paginated gallery.

When I test the view alone, i.e. as the main view of an activity, it works fine. However, when I include this as part of another layout, the scrolling (or flicking) becomes weird. If seems to reset to its original position around halfway through a swipe (really quick flicks are the only thing I've gotten to work so far).

Any ideas what the problem could be ?

Just in case it is of any relevance, the view is inflated from XML and added in a PagerAdapter inherited class.

like image 647
Saad Farooq Avatar asked Feb 07 '12 15:02

Saad Farooq


People also ask

What the difference between ViewPager and ViewPager2?

ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager . If your app already uses ViewPager , read this page to learn more about migrating to ViewPager2 .

How to set ViewPager in Android?

Android ViewPager widget is found in the support library and it allows the user to swipe left or right to see an entirely new screen. Today we're implementing a ViewPager by using Views and PagerAdapter. Though we can implement the same using Fragments too, but we'll discuss that in a later tutorial.

How ViewPager works in Android?

ViewPager - How It Works The idea is that ViewPager works with a PageAdapter to supply the Views that represent each page. The basic idea is that ViewPager keeps track of what page should be visible on the screen and then asks the PagerAdapter to get the View hierarchy that needs to be displayed.

Why use ViewPager?

ViewPager in Android is a class that allows the user to flip left and right through pages of data. This class provides the functionality to flip pages in app. It is a widget found in the support library. To use it you'll have to put the element inside your XML layout file that'll contain multiple child views.


1 Answers

Yeah, ViewPager and other scrolling items don't play well together by default. When I have to do such things, I typically subclass ViewPager to make something that's aware of children that can scroll. Then in my onInterceptTouchEvent() I check whether the hit rect is within that child and don't intercept the touch event so the child has a whack at it. Something like this:

/**
 * Override to not intercept touch events within our scroller if it exists.
 */
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    if(scrollerId != 0) {
        View scroller = findViewById(scrollerId);
        if(scroller != null) {
            Rect rect = new Rect();
            scroller.getHitRect(rect);
            if(rect.contains((int)ev.getX(), (int)ev.getY())) {
                return false;
            }
        }
    }
    return super.onInterceptTouchEvent(ev);
}

Then all you need is a way to set that scrollerId (a simple public method works).

Note another way is if you are using a ScrollView for vertically scrolling elements with ViewPager children, you'll need to go a different direction. Have a subclass of ScrollView that detects vertical scrolling directions and bails for horizontal scrolling so the ViewPager picks it up.

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            xDistance = yDistance = 0f;
            lastX = ev.getX();
            lastY = ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            final float curX = ev.getX();
            final float curY = ev.getY();
            xDistance += Math.abs(curX - lastX);
            yDistance += Math.abs(curY - lastY);
            lastX = curX;
            lastY = curY;
            if (xDistance > yDistance)
                return false;
    }

    return super.onInterceptTouchEvent(ev);
}
like image 154
Brian Dupuis Avatar answered Nov 15 '22 00:11

Brian Dupuis