Aug 29, 2011

Disabling paging/swiping on the Android ViewPager control

After struggling for a while trying to get a perfect image gallery for Android (with the ability for users to swipe left and right to move throughout the entire image set), a new article poped up in my Google Reader. "Horizontal View Swiping with ViewPager" written by @geekyouup was the perfect reading to get my problem solved in no time.

It didn't take long though to realize that I needed something that wasn't supported by the "ViewPager" class: a way to disable swiping until certain condition was met. You can imagine an image gallery on your phone, where you can click an image to reveal its description. Now imagine that you don't want the user to swipe to the next image until the description is hidden again. How to do it? Since there's no much written yet about this library, I wrote (I should say "tweet" instead) to the post author himself. Here is the question and his response:
svpino: @geekyouup Any idea how 2 enable/dis swiping on the ViewPager control? ie: prevent the user 2go 2 the next pay til certain condition is met.

geekyouup: @svpino you'll have to check the source and extend it, a setScrollingEnabled method shouldn't be hard.
At first it seemed to me that I would have to check out the source code, modify it, and use the new version. Crap, there's nothing more annoying for me than doing this. But after taking some fresh air, I read the code and realized that the solution was very simple, just like Richard said.

So the first step was to create a new class which I named "CustomViewPager". The class inherits from "ViewPager" and includes a new method called "setPagingEnabled". To enable / disable the swiping, I just had to overwrite two methods: "onTouchEvent" and "onInterceptTouchEvent". Both will return "false" if the paging was disabled. Here is the full code:
public class CustomViewPager extends ViewPager {

    private boolean enabled;

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onTouchEvent(event);
        }
  
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onInterceptTouchEvent(event);
        }
 
        return false;
    }
 
    public void setPagingEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}

After doing this, the only thing left was to substitute the "ViewPager" tag on the layout file for my own class:
<mypackage.customviewpager 
    android:id="@+id/photosViewPager" 
    android:layout_height="match_parent" 
    android:layout_width="match_parent" />
And that was it. Now, anytime I need to disable the swiping, I just need to call the "setPagingEnabled" method with "false" and users won't be able to switch the images.

Thanks to Richard Hyndman for pointing me to the right direction.

P.S: If you are bored, you can check my newer Android app on Google Play. It's gratis and beautiful.