É possível desativar a rolagem em um ViewPager


138

Eu tenho um ViewPagerque instancia a View. Gostaria de desativar momentaneamente a rolagem do visor e os botões filho enquanto um resultado de pesquisa é retornado à visualização. Estou ligando, viewPager.setEnabled(false)mas isso não o desativa.

Alguém tem alguma idéia?


Respostas:


355

Uma solução simples é criar sua própria subclasse de ViewPagerque possui uma private booleanbandeira isPagingEnabled,. Em seguida, substitua os métodos onTouchEvente onInterceptTouchEvent. Se isPagingEnabledigual a true, invoque o supermétodo, caso contrário return.

public class CustomViewPager extends ViewPager {

    private boolean isPagingEnabled = true;

    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

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

    public void setPagingEnabled(boolean b) {
        this.isPagingEnabled = b;
    }
}

Em seguida, no seu Layout.XMLarquivo, substitua as <com.android.support.V4.ViewPager>tags por <com.yourpackage.CustomViewPager>tags.

Este código foi adaptado desta postagem do blog .


2
solução greate, funciona bem. Se você deseja parar de deslizar como um macaco, é possível substituir um OnPageChangeListener por @Override public void onPageScrollStateChanged (estado final int) {switch (state) {case ViewPager.SCROLL_STATE_SETTLING: mPager.setPagingEnabled (false); pausa; caso ViewPager.SCROLL_STATE_IDLE: mPager.setPagingEnabled (true); pausa; } // noop}
— Informatic0re

13
PS: No XML, use <yourpkgname.CustomViewPager ... em vez de <com.android, support.v4.ViewPager ... #
— thecr0w

Para adicionar outra solução semelhante, você pode usar a biblioteca chamada "JazzyViewPager": github.com/jfeinstein10/JazzyViewPager , e apenas chamar setPagingEnabled (boolean)
— desenvolvedor Android

é possível parar de rolar apenas para a direita? i pode rolagem só deixou
— Saif Hamed

Ainda é possível "rolar" focando elementos (botões, etc.) nas páginas ao usar um controle de jogo ou teclado, por exemplo. Como desativar isso completamente? Eu acho que é um outro tipo de evento que deve ser interceptadas ...
— David Ferrand

34

Existe uma solução fácil para este:

Quando você deseja desativar a rolagem do viewpager:

mViewPager.setOnTouchListener(new OnTouchListener() {

   public boolean onTouch(View arg0, MotionEvent arg1) {
      return true;
   }
}); 

E quando você deseja reativá-lo, então:

mViewPager.setOnTouchListener(null);

Isso será o suficiente.


46
Quase, mas não exatamente. O toque para baixo ainda acontece, para que você possa mover as páginas fazendo vários pequenos deslizamentos.
— Flynny75

@Akhil Sekharan Estava enfrentando o problema exatamente com o que Flynny está enfrentando ao usar esta resposta ... mas, felizmente, não sei como de repente esse erro ocorreu .. :) e funcionou como um encanto!
— Zombie

Você pode fazer os lotes de pequenos furtos assim você ainda tem a mais onInterceptTouchEvent boolean pública (evento MotionEvent) {passeio como por slatons responder
— Ryan Heitner

28

Aqui está minha variante leve da resposta de slayton:

public class DeactivatableViewPager extends ViewPager {
    public DeactivatableViewPager(Context context) {
        super(context);
    }

    public DeactivatableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return isEnabled() && super.onInterceptTouchEvent(event);
    }
}

Com o meu código, você pode desativar a paginação com setEnable().


A substituição onInterceptTouchEvent()impedirá que as visualizações secundárias recebam entrada. Na maioria dos casos, esse não é o comportamento pretendido.
— Alex Semeniuk

19

Encontrei uma solução simples.

//disable swiping
mViewPager.beginFakeDrag();

//enable swiping
mViewPager.endFakeDrag();

Esse é todo o código que você usou? Isso não está funcionando para mim.
— precisa saber é o seguinte

17
Não funciona para mim. Ainda pode fazer muitos pequenos golpes.
— DYS

Este código não é bcz adequada É rolagem muito lentamente como a vista de suspensão
— Ghanshyam Nayma

Isso pode funcionar por sorte. Atualizar para o ViewPager pode quebrar esse hack.
— Pointer Null

Ainda está arrastando, mas pouco a pouco (.
— ekashking 5/11/19

14

Sugiro outra maneira de resolver esse problema. A idéia é agrupar seu viewPager por um scrollView, para que, quando esse scrollView não for rolável, seu viewPager também não seja rolável.

Aqui está o meu layout XML:

        <HorizontalScrollView
            android:id="@+id/horizontalScrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true" >

            <android.support.v4.view.ViewPager
                android:id="@+id/viewPager"
                android:layout_width="wrap_content"
                android:layout_height="match_parent" />

        </HorizontalScrollView>

Nenhum código é necessário.

Funciona bem para mim.


1
Entre todas essas respostas, acho que isso é simples e funciona muito bem !!
— SREE

OK ... mas quando você tem um mapa como um dos fragmento em ViewPager então ... é um problema
— ekashking

4

Para desativar o furto

 mViewPager.beginFakeDrag();

Para ativar o furto

 mViewPager.endFakeDrag();

2
A rolagem ainda é possível, apenas não é mais fluente. Basicamente, isso apenas piora a qualidade sem resolver o problema.
— Benjamin Basmaci 14/03/19

1
resposta duplicada
— Ricardo A.

3

A melhor solução que funcionou para mim é:

public class DeactivatedViewPager extends ViewPager {

    public DeactivatedViewPager (Context context) {
        super(context);
    }

    public DeactivatedViewPager (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean canScrollHorizontally(int direction) {
        return false;
    }
}

Depois disso, a rolagem será desativada pelo toque e você ainda poderá usar o setCurrentItemmétodo para alterar a página.


Não sei por que, mas simplesmente não funcionou. A rolagem ainda acontece.
— Ricardo A.

1
O canScrollHorizontally()método não tem efeito no cenário atual. Nem é chamado quando o furto acontece.
— Alex Semeniuk

3

Aqui está uma resposta em Kotlin e androidX

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.viewpager.widget.ViewPager

class DeactivatedViewPager @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : ViewPager(context, attrs) {

    var isPagingEnabled = true

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        return isPagingEnabled && super.onTouchEvent(ev)
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        return isPagingEnabled && super.onInterceptTouchEvent(ev)
    }
}

2

Que tal isso:
eu usei CustomViewPager
e, em seguida, substituo o scrollTo, para o método que
eu verifiquei o movimento ao fazer muitos pequenos furtos, ele não rola para outras páginas.

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

    @Override
    public void scrollTo(int x, int y) {
       if(enabled) {
          super.scrollTo(x, y);
       }
    }
}

Eu tinha o problema de que o espectador ainda estava fazendo pequenos furtos, mas a substituição View.scrollTo(int x, int y)resolveu esse problema para mim. Obrigado
— Palm

Causa algum comportamento estranho em alguns casos. Como ir ao vazio e deixar apenas uma página em branco '-'
— Ricardo A.

2

No meu caso de usar o ViewPager 2 alfa 2, o trecho abaixo funciona

viewPager.isUserInputEnabled = false

Capacidade de desativar a entrada do usuário (setUserInputEnabled, isUserInputEnabled)

consulte isso para obter mais alterações no viewpager2 1.0.0-alpha02

Também foram feitas algumas alterações na versão mais recente do ViewPager 2 alpha 4

orientação e os atributos isUserScrollable não fazem mais parte do SavedState

consulte isso para obter mais alterações no viewpager2 # 1.0.0-alpha04


1

A nova classe ViewPager2 do androidx permite desativar a rolagem com o método setUserInputEnabled (false)

private val pager: ViewPager2 by bindView(R.id.pager)

override fun onCreate(savedInstanceState: Bundle?) {
    pager.isUserInputEnabled = false
}

0

A resposta de slayton funciona bem. Se você deseja parar de deslizar como um macaco, você pode substituir um OnPageChangeListener por

@Override public void onPageScrollStateChanged(final int state) { 
        switch (state) { 
            case ViewPager.SCROLL_STATE_SETTLING: 
                mPager.setPagingEnabled(false); 
                break; 
            case ViewPager.SCROLL_STATE_IDLE: 
                mPager.setPagingEnabled(true); 
                break; 
        } 
    }

Então você só pode deslizar lado a lado


1
Não encontraram qualquer método de ViewPager tais como setPagingEnabled (valor booleano)
— Rakesh Yadav

setPagingEnabled (valor booleano) deve ser criado por você, pois não existe esse método para substituir.
— quer

Não está claro o que esse setPagingEnabled()método faz. Por favor inclua o código completo.
— Alex Semeniuk

0
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;

public class NonSwipeableViewPager extends ViewPager {

public NonSwipeableViewPager(Context context) {
    super(context);
}

public NonSwipeableViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    // stop swipe 
    return false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // stop switching pages
    return false;
}

private void setMyScroller() {
    try {
        Class<?> viewpager = ViewPager.class;
        Field scroller = viewpager.getDeclaredField("mScroller");
        scroller.setAccessible(true);
        scroller.set(this, new MyScroller(getContext()));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public class MyScroller extends Scroller {
    public MyScroller(Context context) {
        super(context, new DecelerateInterpolator());
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int 
duration) {
        super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
    }
}
}

Em seguida, no arquivo Layout.XML, substitua as tags --- com.android.support.V4.ViewPager --- por --- com.yourpackage.NonSwipeableViewPager ---.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.