Cómo deshabilitar ViewPager de deslizar en una dirección

Quiero permitir que el usuario deslice un ViewPager solo de derecha a izquierda. Entonces, una vez que pasó una página, no puede volver a ella. ¿Cómo puede hacerse esto?

Intenté esta solución:

 public class CustomViewPager extends ViewPager { float lastX = 0; boolean lockScroll = false; public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public CustomViewPager(Context context) { super(context); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: lastX = ev.getX(); lockScroll = false; return super.onTouchEvent(ev); case MotionEvent.ACTION_MOVE: if (lastX > ev.getX()) { lockScroll = false; } else { lockScroll = true; } lastX = ev.getX(); break; } lastX = ev.getX(); if(lockScroll) { return false; } else { return super.onTouchEvent(ev); } } } 

Pero todavía me permite deslizarme mal en la otra dirección.

Hay un evento más que extrañas: onInterceptTouchEvent. Debe contener la misma lógica que onTouchEvent.

Mi solución completa se basa en esta respuesta. Le permitirá activar / desactivar la búsqueda en cualquier dirección en el momento que necesite.

1. Crear enum

  public enum SwipeDirection { all, left, right, none ; } 

2. Extender ViewPager

 public class CustomViewPager extends ViewPager { private float initialXValue; private SwipeDirection direction; public CustomViewPager(Context context, AttributeSet attrs) { super(context, attrs); this.direction = SwipeDirection.all; } @Override public boolean onTouchEvent(MotionEvent event) { if (this.IsSwipeAllowed(event)) { return super.onTouchEvent(event); } return false; } @Override public boolean onInterceptTouchEvent(MotionEvent event) { if (this.IsSwipeAllowed(event)) { return super.onInterceptTouchEvent(event); } return false; } private boolean IsSwipeAllowed(MotionEvent event) { if(this.direction == SwipeDirection.all) return true; if(direction == SwipeDirection.none )//disable any swipe return false; if(event.getAction()==MotionEvent.ACTION_DOWN) { initialXValue = event.getX(); return true; } if(event.getAction()==MotionEvent.ACTION_MOVE) { try { float diffX = event.getX() - initialXValue; if (diffX > 0 && direction == SwipeDirection.right ) { // swipe from left to right detected return false; }else if (diffX < 0 && direction == SwipeDirection.left ) { // swipe from right to left detected return false; } } catch (Exception exception) { exception.printStackTrace(); } } return true; } public void setAllowedSwipeDirection(SwipeDirection direction) { this.direction = direction; } 

3. Utilice su viewPager en un diseño

   

4. Habilitar cualquier dirección de deslizamiento en el código. El valor predeterminado es todo (derecha e izquierda)

 mViewPager.setAllowedSwipeDirection(SwipeDirection.right); 

Defina su adaptador como este

 public class MyFragmentStatePagerAdapter extends FragmentStatePagerAdapter { private final int totalPages = 10; private int currentPage = 0; public MyFragmentStatePagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { // Use whatever logic you want here to // to select a fragment based on // currentPage instead of position if (currentPage % 2 == 0) { return new Fragment1(); } else { return new Fragment2(); } } @Override public int getCount() { return currentPage == totalPages ? 1 : 2; } @Override public int getItemPosition(Object object){ return PagerAdapter.POSITION_NONE; } public void nextPage() { currentPage++; notifyDataSetChanged(); } } 

En el fragmento que está usando el buscapersonas, haz esto

 @Override public void onPageSelected(int arg0) { if (arg0 > 0) { pagerAdapter.nextPage(); pager.setCurrentItem(0, false); } } 

Intenta agregar (la misma lógica que en onTouchEvent)

 @Override public boolean onInterceptTouchEvent(MotionEvent arg0) { // allow/ not allow swiping to switch between pages return !lockScroll ; } 
 package com.contacts_app.jamison.contacts__proprivacy4; import android.content.Context; import android.content.res.Resources; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; public class ViewPager_Settings extends ViewPager { private final String TAG = ViewPager_Settings.class.getSimpleName(); public float startX; public ViewPager_Settings(Context context, AttributeSet attrs) { super(context, attrs); } //////////////////////////////////////////////////////////////////////////////////////////////// public static int dpTOpx(double dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } public static int pxTOdp(double px) { return (int) (px / Resources.getSystem().getDisplayMetrics().density); } //////////////////////////////////////////////////////////////////////////////////////////////// /*****DispatchTouchEvent for the View Pager to intercept and block swipes Right*****/ @Override public boolean dispatchTouchEvent(MotionEvent ev) { final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK; //int movement_limit = pxTOdp(50); switch (actionMasked) { case (MotionEvent.ACTION_DOWN): { startX = ev.getX(); Log.i(TAG, "startX: " + startX); /*Should always be this below*/ return super.dispatchTouchEvent(ev); } case (MotionEvent.ACTION_MOVE): { Log.i(TAG, "ev.getX() - startX:" + (ev.getX() - startX)); /*Switching directional changes would be a matter of flipping the "<" sign in the line below.*/ if (ev.getX() - startX > 0) { /*The result is that the ViewPager will not swipe from left*/ ev.setAction(MotionEvent.ACTION_CANCEL);; } /*Should always be this below*/ super.dispatchTouchEvent(ev); } /**The ACTION_UP case statement is only needed if you don't want to pass down the touch event * to buttons that may receive the click after the swipe is blocked.*/ /*case (MotionEvent.ACTION_UP): { //Log.i(TAG, "movement_limit: " + movement_limit); //(-50) may need to be changed to something more broader in scope to accompany all screen densities if ( (ev.getX() - startX) < (-50) ) { ev.setAction(MotionEvent.ACTION_CANCEL); } //Should always be this below super.dispatchTouchEvent(ev); }*/ } /*Should always be this below*/ return super.dispatchTouchEvent(ev); } //////////////////////////////////////////////////////////////////////////////////////////////// }/*****END OF FILE*****/ 

No olvides cambiar la línea en la parte superior para poner el nombre del paquete de tu aplicación. Además, la mayoría, si no todos, de los comentarios dan una idea de lo que el código está haciendo en caso de que decida que quiere manipular las cosas.

    Intereting Posts