The control that allows you to scroll ViewPager, dynamically with feedback on the interface

I am working on an application that uses many pages for scrolling, however on some pages I would like to prevent scrolling to the next page until they select something.

At the moment, I have expanded ViewPager:

/* (non-Javadoc) * @see android.support.v4.view.ViewPager#onInterceptTouchEvent(android.view.MotionEvent) */ @Override public boolean onInterceptTouchEvent(MotionEvent event) { if (this.canGoLeft || this.canGoRight) { return super.onInterceptTouchEvent(event); } return false; } /* (non-Javadoc) * @see android.support.v4.view.ViewPager#onTouchEvent(android.view.MotionEvent) */ @Override public boolean onTouchEvent(MotionEvent ev) { boolean lockScroll = false; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: lastX = ev.getX(); lockScroll = false; return super.onTouchEvent(ev); case MotionEvent.ACTION_MOVE: if (canGoLeft && lastX < ev.getX()) { lockScroll = false; } else if (canGoRight && lastX > ev.getX()) { lockScroll = false; } else { lockScroll = true; } lastX = ev.getX(); break; } lastX = ev.getX(); if (lockScroll) { //make callback to prevent movement if (mOnPreventCallback != null) { mOnPreventCallback.onPreventMovement(); } return false; } else { return super.onTouchEvent(ev); } } 

Note. I tried to prevent the transition to the previous page, however you can still go to the previous page, but you need to swipe from the far left and swipe to the right. It is temperamental, but it does not stop to hit hard.

Three things I want to do here:

  1. Prevent scrolling to next screen until they select an item or something
  2. Prevent scrolling to the previous screen (partially implemented)
  3. Leave a review for the user to show that scrolling is disabled, similar to how Android displays top and bottom screens with a gradient.
+4
source share
5 answers

When I encountered a similar problem, I made my own listener using gestureDetector and made it so that it does not respond to scrolling at all, you can easily configure it so that it does not respond to scrolling to the right only under certain conditions. This should match your numbers 1 and 2.

This is the listener:

 public class OnSwipeTouchListener implements OnTouchListener { @SuppressWarnings("deprecation") private final GestureDetector gestureDetector = new GestureDetector(new GestureListener()); public boolean onTouch(final View v, final MotionEvent event) { return gestureDetector.onTouchEvent(event); } private final class GestureListener extends SimpleOnGestureListener { private static final int SWIPE_THRESHOLD = 100; private static final int SWIPE_VELOCITY_THRESHOLD = 100; @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { onTouch(e); return true; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { boolean result = false; try { float diffY = e2.getY() - e1.getY(); float diffX = e2.getX() - e1.getX(); if (Math.abs(diffX) > Math.abs(diffY)) { if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { if (diffX > 0) { onSwipeRight(); } else { onSwipeLeft(); } } } else { // onTouch(e); } } catch (Exception exception) { exception.printStackTrace(); } return result; } } public void onTouch(MotionEvent e) { } public void onSwipeRight() { //call this only if your condition was set } public void onSwipeLeft() { //nothing, this means,swipes to left will be ignored } public void onSwipeTop() { } public void onSwipeBottom() { } } 

and this is a usage example:

 viewPager.setOnTouchListener(new OnSwipeTouchListener() { public void onSwipeRight() { if(your conditionIsMet){ // move your pager view to the right } } }); 

It might have been a simpler and more elegant solution, but it worked for me.

+4
source

I work in search engines with high and low efficiency to solve this problem ... I tried to override ontouchevent, etc.

I decided that this is the best solution for me (and less hacks). it was easy to implement the maximum or minimum tracker and set it to the current page

  maxPageToScroll = viewPager.getCurrentItem(); minPageToScroll = viewPager.getCurrentItem(); 

and then add the "onPageSelected" method:

 public void onPageSelected(int position) { if (position < minPageToScroll) { viewPager.setCurrentItem(maxPageToScroll); } else if (position > maxPageToScroll) { viewPager.setCurrentItem(maxPageToScroll); // you can alert here that user needs to do certain actions before proceeding } else { // enter normal commands here } 

therefore, under the conditions, you simply increase maxpage by one.

  maxPageToScroll = viewPager.getCurrentItem() + 1; 

note that this does not prevent the user form from scrolling ... it just prevents the page view pager from viewing.

+2
source

I do not think that a ViewPager extension is necessary. What you need to do is change the list of pages provided by the PagerAdapter on the fly. This means that you check to see if a particular page is marked β€œcompleted,” and only then add the next page to the list. The way ViewPager works.

Take a look at the implementation of the master pager Roman Nurik . There is a recalculateCutOffPage method in MainActivity that does what I said.

+1
source

you can use your own viewing pager

 public class CustomViewPager extends ViewPager { float mStartDragX; OnSwipeOutListener mListener; Context context; public static boolean enabled; public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; enabled = true; } @Override public boolean onTouchEvent(MotionEvent event) { if (enabled) //view pager scrolling enable if true { return super.onTouchEvent(event); } return false; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (enabled)enter code here { return super.onInterceptTouchEvent(ev); } else // view pager disable scrolling { float x = ev.getX(); switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mStartDragX = x; break; case MotionEvent.ACTION_MOVE: if (mStartDragX < x - 100)//100 value velocity { //Left scroll //return super.onInterceptTouchEvent(ev); } else if (mStartDragX > x + 100) { //Right scroll //return super.onInterceptTouchEvent(ev); } break; } } return false; } public void setOnSwipeOutListener(OnSwipeOutListener listener) { mListener = listener; } public interface OnSwipeOutListener { public void onSwipeOutAtStart(); public void onSwipeOutAtEnd(); } 

}

+1
source

I connected a viewpager for the wizard with a maximum page that the user cannot transmit.

In the end, the solution was in the adapter. I changed the PagerAdapter score and thus blocks the user from passing the maximum page:

 @Override public int getCount() { return mProgress; //max page + 1 } 

When the user goes to the next page:

 private void setWizardProgress(int progress) { if(progress > mProgress) { mProgress = progress; mWizardPagerAdapter.notifyDataSetChanged(); } } 

Thus, when the user is on the maximum page, he cannot scroll to the right until the progress is updated.

-1
source

Source: https://habr.com/ru/post/1444578/


All Articles