RecyclerView - Como suavizar a rolagem para o topo do item em uma determinada posição?
Em um RecyclerView, sou capaz de rolar de repente para a parte superior de um item selecionado usando:
No entanto, isso move abruptamente o item para a posição superior. Quero passar para o topo de um item sem problemas .
mas não funciona bem, pois não move o item para a posição selecionada para o topo. Simplesmente rola a lista até o item na posição ficar visível.
RecyclerViewfoi projetado para ser extensível, portanto, não há necessidade de subclassificar o LayoutManager(como sugerido pelo droidev ) apenas para executar a rolagem.
Em vez disso, basta criar um SmoothScrollercom a preferência SNAP_TO_START:
Agora você define a posição em que deseja rolar:
e passe esse SmoothScroller para o LayoutManager:
Obrigado por esta solução mais curta. Apenas mais duas coisas que tive que considerar em minha implementação: como tenho uma exibição de rolagem horizontal, tive que definir protected int getHorizontalSnapPreference() { return LinearSmoothScroller.SNAP_TO_START; }. Além disso, eu tive que implementar o método abstrato public PointF computeScrollVectorForPosition(int targetPosition) { return layoutManager.computeScrollVectorForPosition(targetPosition); }.
— AustrianDude
O RecyclerView pode ser projetado para ser extensível, mas algo simples como esse parece preguiçoso por estar faltando. Boa resposta tho! Obrigado.
Existe alguma maneira de deixá-lo começar, mas com um deslocamento de X dp?
— Mark Buikema
@Alessio exatamente, isso quebrará a funcionalidade smoothScrollToPosition padrão do RecyclerView
é possível diminuir a velocidade?
para isso, você deve criar um LayoutManager personalizado
use isso para o seu RecyclerView e chame smoothScrollToPosition.
isso rolará para o topo do item RecyclerView da posição especificada.
Ocorreu um problema ao implementar o LayoutManager sugerido. Esta resposta aqui funcionou muito mais fácil para mim: stackoverflow.com/questions/28025425/…
Única resposta útil após horas de dor, isso funciona como projetado!
@droidev Usei seu exemplo com rolagem suave e geralmente é o que eu preciso em SNAP_TO_START, mas funciona com alguns problemas para mim. Às vezes, a rolagem para 1,2,3 ou 4 posições anteriores para as quais passo smoothScrollToPosition. Por que esse problema pode ocorrer? Obrigado.
você pode, de alguma forma, acessar seu código para nós? Tenho certeza de que é seu problema de código.
— Droidev 2/11
Esta é a resposta correta, apesar da aceita.
Esta é uma função de extensão que escrevi no Kotlin para usar com a RecyclerView(com base na resposta de @Paul Woitaschek):
Isso funciona! O problema com rolagem suave é quando você tem grandes listas e, em seguida, percorrer a parte inferior ou superior leva um longo, longo tempo
@vovahost como posso centralizar a posição desejada?
— ysfcyln 27/01
@ysfcyln Verifique esta stackoverflow.com/a/39654328/1502079 resposta
— vovahost 27/01
Podemos tentar assim
— Supto
Substitua a função calculDyToMakeVisible / calculDxToMakeVisible em LinearSmoothScroller para implementar a posição Y / X de deslocamento
— user2526517
Era isso que eu estava procurando. Obrigado por compartilhar este para a implementação da posição de deslocamento de x / y :)
A maneira mais fácil que encontrei de rolar a RecyclerViewé a seguinte:
Isso não rolará para uma posição se essa posição já estiver visível. Rola a quantidade mínima necessária para tornar a posição visível. Portanto, por que precisamos daquele com deslocamento especificado.
— TatiOverflow 26/08/19
Obrigado, @droidev pela solução. Se alguém procurando a solução Kotlin, consulte o seguinte:
— PANKAJ KUMAR MAKWANA
Obrigado @pankaj, estava procurando uma solução no Kotlin.
— Akshay Kumar Ambos
Estenda a classe "LinearLayout" e substitua as funções necessárias
Crie uma instância da classe acima em seu fragmento ou atividade
Chame "recyclerView.smoothScrollToPosition (targetPosition)
CustomLinearLayout.kt:
Nota: O exemplo acima está definido na direção HORIZONTAL, você pode passar VERTICAL / HORIZONTAL durante a inicialização.
Se você definir a direção como VERTICAL , altere " CalculateDxToMakeVisible " para " CalculeDyToMakeVisible " (lembre-se também do valor de retorno de chamada de supertipo)
Activity / Fragment.kt :
Provavelmente, a abordagem @droidev é a correta, mas eu só quero publicar algo um pouco diferente, que basicamente faz o mesmo trabalho e não requer extensão do LayoutManager.
Uma NOTA aqui - isso funcionará bem se o seu item (aquele que você deseja rolar no topo da lista) estiver visível na tela e você quiser apenas rolar para o topo automaticamente. É útil quando o último item da sua lista tem alguma ação, que adiciona novos itens à mesma lista e você deseja focar o usuário nos novos itens adicionados:
A idéia é simples: 1. Precisamos obter a coordenada superior do elemento de revisão de reciclagem; 2. Precisamos obter a coordenada superior do item de exibição que queremos rolar para o topo; 3. No final, com o deslocamento calculado, precisamos fazer
200 é apenas um exemplo de valor inteiro codificado que você pode usar se o item do visualizador não existir, porque isso também é possível.
Quero abordar mais detalhadamente a questão da duração da rolagem , que, se você escolher uma resposta anterior, variará de maneira dramática (e inaceitável) de acordo com a quantidade de rolagem necessária para alcançar a posição de destino a partir da posição atual.
Para obter uma duração de rolagem uniforme, a velocidade (pixels por milissegundo) deve ser responsável pelo tamanho de cada item individual - e quando os itens tiverem dimensões fora do padrão, será adicionado um novo nível de complexidade.
Pode ser por isso que os desenvolvedores do RecyclerView implantaram a cesta muito difícil para esse aspecto vital da rolagem suave.
Supondo que você queira uma duração de rolagem semi-uniforme e que sua lista contenha itens semi-uniformes , será necessário algo como isto.