Existe alguma maneira de diminuir a velocidade de rolagem com o adaptador do viewpager no Android?
Você sabe, estive olhando este código. Não consigo descobrir o que estou fazendo de errado.
try{
Field mScroller = mPager.getClass().getDeclaredField("mScroller");
mScroller.setAccessible(true);
Scroller scroll = new Scroller(cxt);
Field scrollDuration = scroll.getClass().getDeclaredField("mDuration");
scrollDuration.setAccessible(true);
scrollDuration.set(scroll, 1000);
mScroller.set(mPager, scroll);
}catch (Exception e){
Toast.makeText(cxt, "something happened", Toast.LENGTH_LONG).show();
}
Isso não muda nada, mas nenhuma exceção ocorre?
child.setNestedScrollingEnabled(false);
trabalhou para mimRespostas:
Comecei com o código de HighFlyer, que de fato mudou o campo mScroller (o que é um ótimo começo), mas não ajudou a estender a duração da rolagem porque o ViewPager passa explicitamente a duração para o mScroller ao solicitar a rolagem.
Estender o ViewPager não funcionou porque o método importante (smoothScrollTo) não pode ser substituído.
Acabei corrigindo isso estendendo o Scroller com este código:
E usando assim:
Basicamente, codifiquei a duração para 5 segundos e fiz meu ViewPager usá-la.
Espero que isto ajude.
fonte
scroller.setFixedDuration(5000);
dá erro? Diz "The method setFixedDuration (int) is undefined"Eu queria fazer sozinho e encontrei uma solução (usando reflexão, no entanto). É semelhante à solução aceita, mas usa o mesmo interpolador e apenas altera a duração com base em um fator. Você precisa usar um
ViewPagerCustomDuration
em seu XML em vez deViewPager
, e então você pode fazer isso:ViewPagerCustomDuration.java
:ScrollerCustomDuration.java
:Espero que isso ajude alguém!
fonte
Eu encontrei uma solução melhor, com base na resposta de @ df778899 e na API Android ValueAnimator . Funciona bem sem reflexão e é muito flexível. Além disso, não há necessidade de tornar o ViewPager personalizado e colocá-lo no pacote android.support.v4.view. Aqui está um exemplo:
fonte
startFakeDrag
eendFakeDrag
destina-se a fazer mais do que o disponívelViewPager
fora da caixa. Isso funciona muito bem para mim e é exatamente o que eu estava procurandoanimatePagerTransition(final boolean forward
método? É sobre isso que estou confuso. Você o chama em um dosViewPager.OnPageChangeListener
métodos de interface? Ou em outro lugar?Como você pode ver nas fontes do ViewPager, a duração do fling controlada pelo objeto mScroller. Em documantation podemos ler:
Portanto, se você quiser controlar a velocidade, pode alterar o objeto mScroller por meio de reflexão.
Você deve escrever algo assim:
fonte
Esta não é a solução perfeita, você não pode tornar a velocidade mais lenta porque é um
int
. Mas, para mim, é lento o suficiente e não preciso usar reflexão.Observe o pacote onde está a classe.
smoothScrollTo
tem visibilidade de pacote.fonte
Notice the package where the class is
.package-local
fields
/methods
, se apenas fizer o Android Studio pensar que está usando o mesmo pacote? Eu sou o único que está sentindo algum cheirosealing violation
?Os métodos fakeDrag no ViewPager parecem fornecer uma solução alternativa.
Por exemplo, esta página vai do item 0 a 1:
(O
count * count
está lá apenas para acelerar o arrasto à medida que avança)fonte
Eu tenho usado
Aqui está o exemplo:
fonte
Com base na solução aceita, criei uma classe kotlin com extensão para visualização de pager. Aproveitar! :)
fonte
Aqui está uma resposta usando uma abordagem totalmente diferente. Alguém pode dizer que isso tem uma sensação de hacker; no entanto, não usa reflexão e eu diria que sempre funcionará.
Encontramos o seguinte código dentro
ViewPager.smoothScrollTo
:Ele calcula a duração com base em algumas coisas. Vê algo que podemos controlar?
mAdapter.getPageWidth
. Vamos implementar ViewPager.OnPageChangeListener em nosso adaptador . Vamos detectar quando o ViewPager está rolando e fornecer um valor falso para a largura . Se eu quiser que a duração sejak*100
, então voltarei1.0/(k-1)
paragetPageWidth
. A seguir está o implemento Kotlin dessa parte do adaptador que transforma a duração em 400:Não se esqueça de adicionar o adaptador como OnPageChangedListener.
Meu caso particular pode assumir com segurança que o usuário não pode deslizar para arrastar entre as páginas. Se você tiver que suportar a sedimentação após um arrasto, precisará fazer um pouco mais de cálculo.
Uma desvantagem é que isso depende desse
100
valor de duração base codificado no ViewPager. Se isso mudar, então suas durações mudam com essa abordagem.fonte
Queria resolver o mesmo problema que todos vocês e esta é a minha solução para o mesmo problema, mas acho que desta forma a solução é mais flexível, pois você pode alterar a duração como quiser e também alterar a interpolação dos valores conforme desejado para obter diferentes efeitos visuais. Minha solução desliza da página "1" para a página "2", portanto, apenas em posições crescentes, mas pode ser facilmente alterada para ir em posições decrescentes fazendo "animProgress - lastFakeDrag" em vez de "lastFakeDrag - animProgress". Acho que esta é a solução mais flexível para realizar esta tarefa.
fonte