Ich versuche, Messaging Art Bildschirm mit RecyclerView zu erstellen, die von unten beginnt und mehr Daten lädt, wenn der Benutzer das obere Ende des Chats erreicht. Aber ich stehe vor diesem seltsamen Thema.
Meine RecyclerView scrollt beim Aufruf von notifyDataSetChanged nach oben. Aus diesem Grund wird onLoadMore mehrmals aufgerufen.
Hier ist mein Code:
%Vor%** Im Adapter
%Vor%** In Aktivität
%Vor%Es ist nur so, dass recyclerView nach oben scrollt. Wenn Sie zu den oberen Stopps scrollen, wird dieses Problem gelöst. Bitte helfen Sie mir, die Ursache dieses Problems herauszufinden. Vielen Dank im Voraus.
Sie sehen, dass es für List
natürlich ist, zum obersten Eintrag zu blättern, wenn Sie neue Objekte einfügen. Nun, du gehst in die richtige Richtung, aber ich glaube, du hast vergessen, setReverseLayout(true)
hinzuzufügen.
Hier zeigt setStackFromEnd(true)
nur List
an, Objekte beginnend am unteren Ende der Ansicht zu stapeln, aber wenn sie in Kombination mit setReverseLayout(true)
verwendet werden, wird die Reihenfolge der Elemente und Ansichten umgekehrt, sodass das neueste Element immer unten angezeigt wird der Ansicht.
Ihr endgültiger LayoutManager würde ungefähr so aussehen:
%Vor%Ich denke, Sie sollten onBindViewHolder nicht auf diese Weise verwenden, diesen Code entfernen, der Adapter sollte nur Modelldaten binden, nicht scrollen.
Normalerweise mache ich den "onLoadMore" so:
In der Aktivität:
%Vor%Dies funktioniert perfekt für mich, und die "totalLoaded" wird verwendet, wenn der Server nicht mehr Nachrichten zurückgibt, um Serveraufrufe zu beenden. Hoffe es hilft dir.
Ich verlasse mich nicht auf onBindViewHolder für diese Art von Dingen. Es kann mehrmals für eine Position aufgerufen werden. Für die Listen, die mehr Option geladen haben, sollten Sie nach der aufgeblähten Recycleransicht so etwas wie diese verwenden.
%Vor%Ich hoffe, es hilft.
Ich empfehle Ihnen, notifyItemRangeInserted
method von RecyclerView.Adapter
für LoadMore
operations zu verwenden. Sie fügen der Liste einen Satz neuer Elemente hinzu, sodass Sie das gesamte Dataset nicht benachrichtigen müssen.
Benachrichtigen Sie alle registrierten Beobachter, dass der aktuell angezeigte itemCount Elemente, die bei positionStart beginnen, wurden neu eingefügt.
Weitere Informationen: Ссылка
Rufen Sie notifyDataSetChanged()
nicht für RecyclerView
auf. Verwenden Sie die neuen Methoden wie notifyItemChanged()
, notifyItemRangeChanged()
, notifyItemInserted()
usw.
Und wenn du notifyItemRangeInserted()
-
rufen Sie danach nicht die Methode setAdapter()
auf!!
Sie müssen das Element in einem bestimmten Bereich wie folgt nicht angeben:
%Vor%Checkout Firebase Friendlychat Quellcode auf Github .
Es verhält sich wie Sie wollen, speziell bei:
%Vor% Sie haben dieses Problem, denn jedes Mal, wenn Ihre Bedingung wahr ist, rufen Sie loadMore
method even loadMore
war im laufenden Zustand, um dieses Problem zu lösen, müssen Sie einen booleschen Wert in Ihrem Code setzen und das auch überprüfen.
überprüfe meinen folgenden Code, um klarer zu werden.
1- Deklarieren Sie einen booleschen Wert in Ihrer Adapterklasse
2- setze es in deinem Zustand auf wahr
3- setze es auf false, nachdem du Daten aus der Datenbank bekommen hast und deinen Adapter benachrichtigt hast.
Ihr Code muss also wie folgt aussehen:
%Vor%in Aktivität:
%Vor% Dies muss Ihr Problem beheben, aber ich bevorzuge es, loadMore
innerhalb der Aktivität oder Presenter-Klasse mit addOnScrollListener
auf RecyclerView
zu behandeln und zu überprüfen, ob findFirstVisibleItemPosition
in LayoutManager
0 ist und dann Daten lädt.
Ich habe eine Bibliothek für die Paginierung geschrieben, die ich gerne benutze oder benutze.
PS: Wie bereits erwähnt, verwenden Sie nicht notifyDataSetChanged
, da dies alle sichtbaren Ansichten aktualisiert, die nicht aktualisiert werden sollen. Verwenden Sie stattdessen notifyItemRangeInsert
. In diesem Fall müssen Sie von 0 bis angeben Größe der geladenen Daten aus der Datenbank.
In deinem Fall, wenn du von oben lädst, wird notifyDataSetChanged
die Scroll-Position an die Spitze der neu geladenen Daten setzen, also musst du notifyItemRangeInsert
verwenden, um in deiner App ein gutes Gefühl zu bekommen
Sie müssen das Element in einem bestimmten Bereich nicht angeben
%Vor%