ViewPager detects when a user tries to push out of limits

I am using a 6-page ViewPager to display some data. I want to be able to call the method when the user is at position 0, and tries to move right (back) or at position 5 and tries to move left (forward), even if for these pages there are no more direction pages. Is there any way to listen to these scripts?

+28
android
Nov 12
source share
5 answers

Extend ViewPager and override onInterceptTouchEvent() as follows:

 public class CustomViewPager extends ViewPager { float mStartDragX; OnSwipeOutListener mListener; public void setOnSwipeOutListener(OnSwipeOutListener listener) { mListener = listener; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { float x = ev.getX(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mStartDragX = x; break; case MotionEvent.ACTION_MOVE: if (mStartDragX < x && getCurrentItem() == 0) { mListener.onSwipeOutAtStart(); } else if (mStartDragX > x && getCurrentItem() == getAdapter().getCount() - 1) { mListener.onSwipeOutAtEnd(); } break; } return super.onInterceptTouchEvent(ev); } public interface OnSwipeOutListener { public void onSwipeOutAtStart(); public void onSwipeOutAtEnd(); } } 
+42
Nov 12 '12 at 15:59
source share
β€” -

The answer from Flavio Faria does not work for me. The only event that I get onInterceptTouchEvent () is the ACTION_DOWN event. Therefore, I override the onTouchEvent () method to make it work.

Here is the code. Note that I only have onSwipeOutAtEnd () in the listener. You can add your code to support scrolling left on the first vier.

 public class CustomViewPager extends ViewPager { float mStartDragX; OnSwipeOutListener mListener; public void setOnSwipeOutListener(OnSwipeOutListener listener) { mListener = listener; } @Override public boolean onTouchEvent(MotionEvent ev){ if(getCurrentItem()==getAdapter().getCount()-1){ final int action = ev.getAction(); float x = ev.getX(); switch(action & MotionEventCompat.ACTION_MASK){ case MotionEvent.ACTION_DOWN: mStartDragX = x; break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: if (x<mStartDragX){ mListener.onSwipeOutAtEnd(); }else{ mStartDragX = 0; } break; } }else{ mStartDragX=0; } return super.onTouchEvent(ev); } public interface OnSwipeOutListener { public void onSwipeOutAtEnd(); } 
+15
Jun 07 '13 at 20:52
source share

How about installing OnPageChangeListener on your ViewPager? You can then change your navigation arrows or whatever onPageScrolled.

 viewPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { updateNavigationArrows(); } @Override public void onPageScrollStateChanged(int state) { } }); 
+14
Jun 04 '13 at 10:18
source share

Thank you very much @Flavio, although I had to make some changes to its code because the callback methods fired twice, I also added a code to check if there is a registered listener to avoid the application crashing when there is no listener registered. This is the code I used to make it work: with onSwipeOutAtStart and onSwipeOutAtEnd:

 public class CustomViewPager extends android.support.v4.view.ViewPager { float mStartDragX; OnSwipeOutListener mOnSwipeOutListener; public CustomViewPager(Context context) { super(context); } public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public void setOnSwipeOutListener(OnSwipeOutListener listener) { mOnSwipeOutListener = listener; } private void onSwipeOutAtStart() { if (mOnSwipeOutListener!=null) { mOnSwipeOutListener.onSwipeOutAtStart(); } } private void onSwipeOutAtEnd() { if (mOnSwipeOutListener!=null) { mOnSwipeOutListener.onSwipeOutAtEnd(); } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch(ev.getAction() & MotionEventCompat.ACTION_MASK){ case MotionEvent.ACTION_DOWN: mStartDragX = ev.getX(); break; } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev){ if(getCurrentItem()==0 || getCurrentItem()==getAdapter().getCount()-1){ final int action = ev.getAction(); float x = ev.getX(); switch(action & MotionEventCompat.ACTION_MASK){ case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: if (getCurrentItem()==0 && x>mStartDragX) { onSwipeOutAtStart(); } if (getCurrentItem()==getAdapter().getCount()-1 && x<mStartDragX){ onSwipeOutAtEnd(); } break; } }else{ mStartDragX=0; } return super.onTouchEvent(ev); } public interface OnSwipeOutListener { void onSwipeOutAtStart(); void onSwipeOutAtEnd(); } } 
+12
Jun 12 '15 at 10:24
source share

I wonder how it worked for others, it does not work for me.

onInterceptTouchEvent() accepts only the ACTION_DOWN event. So far, onTouchEvent() accepts only one event at a time: ACTION_DOWN , ACTION_UP and others.

I had to override both onInterceptTouchEvent() and onTouchEvent() to make it work correctly. ACTION_DOWN of onInterceptTouchEvent captures the starting point of X , and OnTouchEvent captures the ending point of X2 . Which I compared it to determine the direction of movement.

Get the initial value of X touch:

 float x1 = 0; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch(ev.getAction() & MotionEventCompat.ACTION_MASK){ case MotionEvent.ACTION_DOWN: x1 = ev.getX(); break; } return super.onInterceptTouchEvent(ev); } 

From the tjlian616 code, onTouchEvent() listens for ACTION_UP and gets its last X value. So far, I have established that the current value of the element is 0 to get swipe in the start listening. Compare it and add an activated listener.

  @Override public boolean onTouchEvent(MotionEvent ev){ if(getCurrentItem()==0){ final int action = ev.getAction(); switch(action & MotionEventCompat.ACTION_MASK){ case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: mStartDragX = ev.getX(); if (x1<mStartDragX){ Log.i("TOUCH: ", "ACTION UP " + x1 + " : " + mStartDragX ); mListener.onSwipeOutAtStart(); }else{ Log.i("TOUCH ELSE : ", "ACTION UP " + x1 + " : " + mStartDragX ); mStartDragX = 0; } break; } }else{ mStartDragX=0; } return super.onTouchEvent(ev); } 
+3
Sep 04 '14 at 3:40
source share



All Articles