android - fragments - ViewPager deshabilita deslizar a una determinada dirección
viewpager disable swipe (7)
Quiero desactivar el deslizamiento, pero solo hacia el lado derecho. Encontré una solución de trabajo en this respuesta. Desafortunadamente, esto copia toda la fuente de ViewPager
para lograr el objetivo. ¿Hay algún método que simplemente herede la clase existente y no se duplica?
Aquí está trabajando la clase ViewPager con posibilidad de deshabilitar cualquier paginación de la dirección. Echa un vistazo a todas las respuestas aquí .
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;
}
No estoy seguro de que esto sea exactamente lo que necesita: necesitaba un viewpager para un asistente con una página máxima que el usuario no puede pasar.
Al final la solución estaba en el adaptador. Cambié el número de PagerAdapter y de esta manera bloquea al usuario para que no pase la página máxima:
@Override
public int getCount() {
return mProgress; //max page + 1
}
Cuando el usuario avanza a la siguiente página:
private void setWizardProgress(int progress) {
if(progress > mProgress) {
mProgress = progress;
mWizardPagerAdapter.notifyDataSetChanged();
}
}
De esta manera, cuando el usuario está en la página máxima, no puede desplazarse hacia la derecha.
Otra forma sencilla es usar setCurrentItem () para volver a la diapositiva deseada si llegas a una determinada posición. Por ejemplo, esto solo permitirá deslizar hacia delante:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
@Override
public void onPageSelected(int position) {
if(position < mProgress) {
mViewPager.setCurrentItem(mProgress, true);
} else {
mProgress = position;
}
}
@Override
public void onPageScrollStateChanged(int state) {}
});
O si quieres tener una diapositiva máxima:
if(position > 4) {
mViewPager.setCurrentItem(4, true);
}
Esta solución técnicamente no deshabilitará completamente el deslizamiento, ya que aún verá una pequeña parte de la diapositiva no permitida cuando realice el movimiento de deslizamiento. Pero para algunas aplicaciones esto puede ser preferido.
Puede usar los métodos beginFakeDrag()
y endFakeDrag()
.
beginFakeDrag()
cuando desee desactivar el deslizamiento y endFakeDrag()
si desea habilitar nuevamente.
Así: viewPager.beginFakeDrag();
Puedes intentar lo siguiente:
Paso 1: Cree una nueva clase personalizada diga " CustomViewPager
". La clase se hereda de " ViewPager
" e incluye un nuevo método personalizado llamado " setPagingEnabled
" con el propósito de habilitar / deshabilitar el deslizamiento, según el requisito.
Paso 2: reemplaza dos métodos: " onTouchEvent
" y " onInterceptTouchEvent
". Ambos devolverán " false
" si la paginación se deshabilitará completamente.
Paso 3: Sustituya la etiqueta " ViewPager
" en el archivo de diseño con una clase personalizada:
<package_name.customviewpager
android:id="@+id/customViewPager"
android:layout_height="match_parent"
android:layout_width="match_parent" />
Paso 4: CustomViewPager.java
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 && detectSwipeToRight(event)) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.enabled && detectSwipeToRight(event)) {
return super.onInterceptTouchEvent(event);
}
return false;
}
// To enable/disable swipe
public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
// Detects the direction of swipe. Right or left.
// Returns true if swipe is in right direction
public boolean detectSwipeToRight(MotionEvent event){
int initialXValue = 0; // as we have to detect swipe to right
final int SWIPE_THRESHOLD = 100; // detect swipe
boolean result = false;
try {
float diffX = event.getX() - initialXValue;
if (Math.abs(diffX) > SWIPE_THRESHOLD ) {
if (diffX > 0) {
// swipe from left to right detected ie.SwipeRight
result = false;
} else {
// swipe from right to left detected ie.SwipeLeft
result = true;
}
}
}
catch (Exception exception) {
exception.printStackTrace();
}
return result;
}
}
Tiene que crear su propia subclase ViewPager y anular la función canScrollHorizontally
private float initialXValue;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.mEnabled) {
return super.onTouchEvent(event);
}
if(event.getAction()==MotionEvent.ACTION_DOWN){
initialXValue = event.getX();
}else if(event.getAction()==MotionEvent.ACTION_MOVE){
if(detectSwipeToRight(event)){
System.out.println("right swipe detected");
}
}
return true;
}
private boolean detectSwipeToRight(MotionEvent event) {
final int SWIPE_THRESHOLD = 100; // detect swipe
boolean result = false;
try {
float diffX = event.getX() - initialXValue;
if (Math.abs(diffX) > SWIPE_THRESHOLD) {
if (diffX < 0) {
// swipe from right to left detected ie.SwipeLeft
result = true;
}
}
} catch (Exception exception) {
exception.printStackTrace();
}
return result;
}