Cómo deshabilitar o habilitar el deslizamiento del visor en Android

78

Lo que estoy tratando de hacer: estoy tratando de habilitar / deshabilitar el deslizamiento en el localizador de manera programática cuando el programa se está ejecutando

Ej .: Cuando esté en el flujo si verifico una condición y si regresa,truehabilite el deslizamiento, y si la condición regresafalsedeshabilite el deslizamiento.


La solución que estoy usando es esta

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

Luego, seleccione esto en lugar del visor incorporado en XML

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

Solo necesita llamar al método "setPagingEnabled" con "false" y los usuarios no podrán deslizar el dedo para paginar.


Problema con la metodología anterior: no puedo establecer la propiedad en el flujo, yo: e .... Puedo habilitar el deslizamiento o deshabilitar el deslizamiento. Pero no puedo hacer esto por condición


Pregunta:

  1. ¿Puedo lograr mi objetivo de alguna otra manera? Si es así, ¿cuál es?
  2. O esto no es posible ?
Devrath
fuente
¿No sería posible establecer la propiedad en el flujo con DataBinding?
dios mayor
Intente usar stackoverflow.com/a/42687397/4559365
Pradeep Kumar Kushwaha

Respuestas:

62

Deshabilitar el deslizamiento de forma progresiva

    final View touchView = findViewById(R.id.Pager); 
    touchView.setOnTouchListener(new View.OnTouchListener() 
    {         
        @Override
        public boolean onTouch(View v, MotionEvent event)
        { 
           return true; 
        }
     });

y usa esto para deslizar manualmente

touchView.setCurrentItem(int index);
Ajeet
fuente
55
Esto todavía permite que el visor se deslice parcialmente (como 1%) antes de que se detenga. Se ve feo.
IgorGanapolsky
8
Su solución funciona, es simplemente incompleta. También debe anular onInterceptTouchEvent (evento MotionEvent) también. Esto le dará el aspecto que desea sin el 1%
portfoliobuilder
2
No se puede anular ese método
Animesh Mangla
funciona pero cuando está habilitado, deslizar es muy malo y lento
faeze saghafi
5
esta es una solución absolutamente incorrecta, ¿por qué tantas estrellas? De hecho, se ve feo, con un deslizamiento del 1%. Probablemente, deberíamos extender viewpager y anular onInterceptTouchEvent
Anton Kizema
75

La mejor solución para mi -Primero, creas una clase como esta:

public class CustomViewPager extends ViewPager {
  private Boolean disable = false;
  public CustomViewPager(Context context) {
      super(context);
  }
  public CustomViewPager(Context context, AttributeSet attrs){
      super(context,attrs);
  }
  @Override
  public boolean onInterceptTouchEvent(MotionEvent event) {
     return !disable && super.onInterceptTouchEvent(event);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
     return !disable && super.onTouchEvent(event);
  }

  public void disableScroll(Boolean disable){
      //When disable = true not work the scroll and when disble = false work the scroll
      this.disable = disable;
  }
}

-Entonces cambia esto en tu diseño: <android.support.v4.view.ViewPager para esto<com.mypackage.CustomViewPager

-Finalmente, puedes deshabilitarlo: view_pager.disableScroll(true); o habilitarlo:view_pager.disableScroll(false);

Espero que esto te ayude :)

Alberto
fuente
Gracias Alberto :)
Praveen Kumar Verma
1
Además, no olvide llamar al método viewPager.invalidate () después de llamar al método de deshabilitación de desplazamiento, por lo que deshabilita instantáneamente el deslizamiento.
Ritesh Adulkar
Con esta solución, las vistas dentro de ViewPager no recibirán ninguna entrada si disable == true. Anular onInterceptTouchEvent()no es la solución correcta.
Alex Semeniuk
en lugar de booleano, prefiero usar booleano aquí.
hgoebl
Gracias. Tu respuesta me ayudó a mejorar una función de trabajo.
AndyN
19

En su adaptador de buscapersonas de vista personalizada, anule esos métodos en ViewPager.

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

Y para habilitar, simplemente devuelva cada supermétodo:

super.onInterceptTouchEvent(event)y super.onTouchEvent(event).

Florescu Cătălin
fuente
4

Para deshabilitar el deslizamiento

mViewPager.beginFakeDrag();

Para habilitar deslizar

if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();

Sanjay Bhalani
fuente
¿Puedes elaborar tu consulta?
Sanjay Bhalani
Intento usar esta solución, pero arrojará NullPointerException al llamar a endFakeDrag.
Mia
intente utilizar una condición como. if (mViewPager.isFakeDragging ()) mViewPager.endFakeDrag ();
Sanjay Bhalani
3

En mi caso, la solución simplificada funcionó bien. El método de anulación debe estar en su adaptador de visor personalizado para anular a los oyentes de TouchEvent y hacer que se congelen;

@Override
public boolean onTouchEvent(MotionEvent event) {
    return this.enabled && super.onTouchEvent(event);

}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return this.enabled && super.onInterceptTouchEvent(event);

}
Eric
fuente
proporcionar una explicación sobre la solución proporcionada
Anantha Raju C
1
@AnanthaRajuC proporcionado :)
Eric
Con esta solución, las vistas dentro de ViewPager no recibirán ninguna entrada si this.enabled == false. Anular onInterceptTouchEvent()no es la solución correcta.
Alex Semeniuk
2

Encontré otra solución que funcionó para mí siga este enlace

https://stackoverflow.com/a/42687397/4559365

Básicamente, anula el método canScrollHorizontallypara deshabilitar el deslizamiento con el dedo. Sin setCurrentItemembargo, todavía funciona.

Pradeep Kumar Kushwaha
fuente
El canScrollHorizontally()método no tiene ningún efecto en el escenario actual. Ni siquiera se llama cuando ocurre el deslizamiento.
Alex Semeniuk
1

Esto funcionó para mí.

   ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            // disable swipe
            if(!swipeEnabled) {
                if (viewPager.getAdapter().getCount()>1) {
                    viewPager.setCurrentItem(1);
                    viewPager.setCurrentItem(0);
                }
            }
        }
        public void onPageScrollStateChanged(int state) {}
        public void onPageSelected(int position) {}
    };
    viewPager.addOnPageChangeListener(onPageChangeListener);
Chris Gunawardena
fuente
1

Si desea ampliarlo solo porque necesita un comportamiento No deslizable, no es necesario que lo haga. ViewPager2 proporciona una propiedad agradable llamada:isUserInputEnabled

Arsalan Mehmood
fuente