RecyclerView scrollt nach oben auf notifyDataSetChanged im Chat-Bildschirm

9

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.

    
user1288005 30.03.2017, 16:25
quelle

9 Antworten

1

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%     
Keivan Esbati 16.04.2017 06:18
quelle
1

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.

    
Borja 19.04.2017 06:48
quelle
0

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.

    
letitthebee 30.03.2017 17:13
quelle
0

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.

%Vor%
  

Benachrichtigen Sie alle registrierten Beobachter, dass der aktuell angezeigte itemCount   Elemente, die bei positionStart beginnen, wurden neu eingefügt.

Weitere Informationen: Ссылка

    
savepopulation 12.04.2017 07:26
quelle
0

Rufen Sie notifyDataSetChanged() nicht für RecyclerView auf. Verwenden Sie die neuen Methoden wie notifyItemChanged() , notifyItemRangeChanged() , notifyItemInserted() usw. Und wenn du notifyItemRangeInserted() -

benutzt

rufen Sie danach nicht die Methode setAdapter() auf!!

    
Shobhit 16.04.2017 07:16
quelle
0

Sie müssen das Element in einem bestimmten Bereich wie folgt nicht angeben:

%Vor%     
Burhanuddin Rashid 18.04.2017 05:47
quelle
0

Checkout Firebase Friendlychat Quellcode auf Github .

Es verhält sich wie Sie wollen, speziell bei:

%Vor%     
gustavogbc 18.04.2017 20:00
quelle
0

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

    
Shayan Pourvatan 18.04.2017 04:21
quelle
0

Sie müssen das Element in einem bestimmten Bereich nicht angeben

%Vor%     
Harsh Singhal 19.04.2017 07:08
quelle