Comment faites défiler vers le bas d'un RecyclerView? scrollToPosition ne fonctionne pas
J'aimerais faire défiler vers le bas de la RecyclerView liste après le chargement de l'activité.
GENERIC_MESSAGE_LIST = (ArrayList) intent.getExtras().getParcelableArrayList(ConversationsAdapter.EXTRA_MESSAGE);
conversationView = (RecyclerView) findViewById(R.id.list_messages);
conversationView.setHasFixedSize(true);
conversationViewLayoutManager = new LinearLayoutManager(this);
conversationView.setLayoutManager(conversationViewLayoutManager);
conversationViewAdapter = new ConversationAdapter(GENERIC_MESSAGE_LIST, this);
conversationView.setAdapter(conversationViewAdapter);
conversationView.scrollTo(...)
déclenche une exception n'étant pas pris en charge dans RecyclerView, et conversationView.scrollToPosition(...)
ne semble pas faire quoi que ce soit.
Après le bloc de code, j'ai ajouté
conversationView.scrollToPosition(GENERIC_MESSAGE_LIST.size() + 1)
qui ne fonctionne pas. Il y a 30 éléments dans GENERIC_MESSAGE_LIST
.
- Êtes-vous en faveur
scrollToPosition
immédiatement après la définition de la carte? - oui, c'est juste après
conversationView.setAdapter(conversationViewAdapter);
. - C'est probablement parce que vous êtes en appelant le +1 au lieu de -1 pour le 5ème élément serait la position [4], car il commence à 0. Faire +1 serait de vous donner un ArrayOutOfBounds ... n'est-ce pas planter là?
- Ajouter, après setadapter mRecyclerView.scrollToPosition(carsList.size()-1);
Vous devez vous connecter pour publier un commentaire.
Juste mis
setStackFromEnd=true
ousetReverseLayout=true
ainsi que d'une MAÎTRISE en va éléments de mise en page à partir de la fin.La différence entre ces deux, c'est que
setStackFromEnd
va définir la vue pour afficher le dernier élément, l'orientation de la page restera le même. (Ainsi, dans une de gauche à droite horizontale Recycleur de Vue, le dernier élément sera affiché et le défilement vers la gauche pour afficher les premiers éléments)Alors que
setReverseLayout
va changer l'ordre des éléments ajoutés par la Carte. La présentation débutera à partir du dernier élément, qui sera le plus à gauche dans une LTR Recycleur de Vue et puis, le défilement à la droite affiche les premiers éléments.Exemple:
Voir la documentation pour plus de détails.
Je regardais ce post pour savoir la réponse, mais... je pense que tout le monde sur ce post a été confronté au même cas de figure que moi:
scrollToPosition()
a été complètement ignorée, pour une évidente raison.Ce que j'ai été en utilisant?
... ce TRAVAILLÉ?
recyclerView.scrollToPosition(messages.size()-1);
fonctionne vraiment pour moi, je me demande la raison.smoothScrollToPosition(...)
.reverseLayout = true
etstackFromEnd = true
jeu, faites défiler jusqu'à0
parce que c'est l'élément le plus bas.Je sais que je suis en retard pour répondre ici, si quelqu'un veut savoir la solution est ci-dessous
conversationView.smoothScrollToPosition(conversationView.getAdapter().getItemCount() **-1**);
comme des positions dans les listes sont basés sur zéro.Ajoutez le code suivant après l'envoi de message et avant d'arriver message du serveur
À déroulant à partir de n'importe quelle position dans la recyclerview à bas
Lorsque vous appelez
setAdapter
, qui n'est pas immédiatement mise en page et la position des éléments sur l'écran (qui prend une seule passe de mise en page) et donc votrescrollToPosition()
d'appel n'a pas d'éléments réels pour faire défiler jusqu'à quand vous l'appelez.Au lieu de cela, vous devez vous inscrire à un ViewTreeObserver.OnGlobalLayoutListener (via addOnGlobalLayoutListner() à partir d'un
ViewTreeObserver
créé parconversationView.getViewTreeObserver()
) qui retarde votrescrollToPosition()
jusqu'après la première passe de mise en page:OnGlobalLayoutListener
probablement pas supprimé parce que vous êtes à la vérification devto.isAlive()
. Je ne sais pas la raison, maisViewTreeObserver
est parfois changé pour unView
, donc au lieu de vérifierisAlive
il est préférable de simplement obtenir en coursViewTreeObserver
avecconversationView.getViewTreeObserver().removeGlobalOnLayoutListener
Solution pour Kotlin:
appliquer le code ci-dessous après le réglage de "recyclerView.la carte" ou après "recyclerView.l'adaptateur.notifyDataSetChanged()"
et
code ci-dessus fonctionne, mais il n'est pas bon et pas cool.
SI vous avez l'adaptateur attaché avec recyclerView puis il suffit de faire cela.
mRecyclerView.smoothScrollToPosition(mRecyclerView.getAdapter().getItemCount());
Roc réponse est d'une grande aide. Je voudrais ajouter un petit bloc à elle:
Dans mon cas où les points de vue n'ont pas la même hauteur, appelant scrollToPosition sur le LayoutManager travaillé vraiment faites défiler vers le bas et de voir entièrement le dernier élément:
Dans Kotlin:
GlobalLayoutListener
! Après le refactoring, j'ai eu à utiliser votre méthode pour les faire défiler. N'oubliez pas de retirer l'auditeur comme dans stackoverflow.com/questions/28264139/..., ou vous ne faites défiler RecyclerView retour au début.Cela fonctionne parfaitement bien pour moi:
Seulement Ian réponse a été en mesure de faire de mon
RecyclerView
faites défiler jusqu'à une position spécifiée. Cependant, LaRecyclerView
n'a pas été capable de faire défiler par la suite lorsque je l'ai utiliséscrollToPosition()
.smoothScrollToPosition()
travaillé mais l'animation fait trop lent quand la liste est longue.La raison en était que l'auditeur n'a pas été supprimé. J'ai utilisé le code ci-dessous pour supprimer le
ViewTreeObserver
et cela a fonctionné comme un charme.ce code vous donnera derniers post tout d'abord, je pense que cette réponse est utile.
Essayé une méthode de @galex, il a travaillé jusqu'à ce que le refactoring. J'ai donc utilisé une réponse de @yanchenko et un peu changé. C'est probablement parce que j'ai appelé le défilement de
onCreateView()
, où un fragment de vue a été construit (et probablement n'ont pas la bonne taille).Vous pouvez également ajouter une case de
viewTreeObserver.isAlive
comme dans https://stackoverflow.com/a/39001731/2914140.Première de défilement lors de l'entrée en recycleur premier temps, puis utiliser
linearLayoutManager.scrollToPositionWithOffset(messageHashMap.size()-1,mettez au moins pour faire défiler vers le bas pour défiler jusqu'à mettre en valeur positive);
si la vue est très grand en hauteur puis scrolltoposition décalage particulier est utilisé pour le haut de la vue, puis vous utilisez
int overallXScroldl =chatMessageBinding.rvChat.computeVerticalScrollOffset();
chatMessageBinding.rvChat.smoothScrollBy(0, Math.abs(overallXScroldl));