Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?

I have ViewPager and below it I have 10 buttons. By clicking on button, for example #4, the pager goes immediately to page #4 by mPager.setCurrentItem(3);. But, I want to disable the paging by swiping with finger horizontally. Thus, the paging is done ONLY by clicking on the buttons. So, how I can disable the swiping with finger?

like image 212
theateist Avatar asked Mar 10 '12 21:03

theateist


People also ask

How do I turn off swipe in ViewPager?

To enable / disable the swiping, just overide two methods: onTouchEvent and onInterceptTouchEvent . Both will return "false" if the paging was disabled. You just need to call the setPagingEnabled method with false and users won't be able to swipe to paginate.


2 Answers

You need to subclass ViewPager. onTouchEvent has a lot of good things in it that you don't want to change like allowing child views to get touches. onInterceptTouchEvent is what you want to change. If you look at the code for ViewPager, you'll see the comment:

    /*      * This method JUST determines whether we want to intercept the motion.      * If we return true, onMotionEvent will be called and we do the actual      * scrolling there.      */ 

Here's a complete solution:

First, add this class to your src folder:

import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.animation.DecelerateInterpolator; import android.widget.Scroller; import java.lang.reflect.Field;  public class NonSwipeableViewPager extends ViewPager {      public NonSwipeableViewPager(Context context) {         super(context);         setMyScroller();     }      public NonSwipeableViewPager(Context context, AttributeSet attrs) {         super(context, attrs);         setMyScroller();     }      @Override     public boolean onInterceptTouchEvent(MotionEvent event) {         // Never allow swiping to switch between pages         return false;     }      @Override     public boolean onTouchEvent(MotionEvent event) {         // Never allow swiping to switch between pages         return false;     }      //down one is added for smooth scrolling      private void setMyScroller() {         try {             Class<?> viewpager = ViewPager.class;             Field scroller = viewpager.getDeclaredField("mScroller");             scroller.setAccessible(true);             scroller.set(this, new MyScroller(getContext()));         } catch (Exception e) {             e.printStackTrace();         }     }      public class MyScroller extends Scroller {         public MyScroller(Context context) {             super(context, new DecelerateInterpolator());         }          @Override         public void startScroll(int startX, int startY, int dx, int dy, int duration) {             super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);         }     } } 

Next, make sure to use this class instead of the regular ViewPager, which you probably specified as android.support.v4.view.ViewPager. In your layout file, you'll want to specify it with something like:

<com.yourcompany.NonSwipeableViewPager     android:id="@+id/view_pager"     android:layout_width="match_parent"     android:layout_height="0dp"     android:layout_weight="1" /> 

This particular example is in a LinearLayout and is meant to take up the entire screen, which is why layout_weight is 1 and layout_height is 0dp.

And setMyScroller(); method is for smooth transition

like image 73
louielouie Avatar answered Oct 05 '22 12:10

louielouie


The more general extension of ViewPager would be to create a SetPagingEnabled method so that we can enable and disable paging on the fly. To enable / disable the swiping, just overide two methods: onTouchEvent and onInterceptTouchEvent. Both will return "false" if the paging was disabled.

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;     }  } 

Then select this instead of the built-in viewpager in XML

<mypackage.CustomViewPager      android:id="@+id/myViewPager"      android:layout_height="match_parent"      android:layout_width="match_parent" /> 

You just need to call the setPagingEnabled method with false and users won't be able to swipe to paginate.

like image 22
Rajul Avatar answered Oct 05 '22 11:10

Rajul