Freitag, 9. Mai 2014

Disable horizontal scrolling for ViewPager

Depending on the state of your application it might become necessary to make your ViewPager not scroll horizontally when the user makes a swiping gesture. One use case for this is displaying multiple images in a ViewPager that can be zoomed into and you want the user only to be able to swipe to the next image when it is fully zoomed out. Swiping gestures that are carried out when having zoomed into the image should pan the image contents and not switch to the next one. There is an elegant way to achieve this behaviour by overriding canScroll() in ViewPager. Here's how to disable horizontal swiping temporarily:
public class GalleryViewPager extends ViewPager {
    ...
    @Override
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
        GalleryImage image = getImage();
        if(image.isZoomed()) {
            /* the child view of the ViewPager can scroll, so the ViewPager would not change page */
            return true;
        }
        else {
            /* let base class decide what to do */
            return super.canScroll(v, checkV, dx, x, y);
        }
    }
    ...
}
By returning true from canScroll() we indicate that the child view of the ViewPager itself can scroll, so the ViewPager will not change to the next page, effectively disabling horizontal scrolling for the ViewPager.