Ich möchte ändern ListView
zu RecyclerView
. Ich möchte das onScroll
von OnScrollListener
in verwenden, RecyclerView
um festzustellen, ob ein Benutzer zum Ende der Liste gescrollt hat.
Woher weiß ich, ob ein Benutzer zum Ende der Liste blättert, um neue Daten von einem REST-Service abzurufen?
cwac-endless
fürListView
.Antworten:
Danke an @Kushal und so habe ich es umgesetzt
Vergiss nicht hinzuzufügen
quelle
StaggeredGridLayoutManager
mLayoutManager.findLastCompletelyVisibleItemPosition()==mLayoutManager.getItemCount()-1
findFirstVisibleItemPosition()
nicht gelöst haben, sollten SieRecyclerView.LayoutManager
zuLinearLayoutManager
loading = true
wieder zu machen?loading = true
nach dem//Do pagination
Teil hinzuzufügen . Andernfalls wird dieser Code nur einmal ausgeführt und Sie können kein weiteres Element laden.Machen Sie diese Variablen.
Für die Recycler-Ansicht auf Scrollen setzen.
und für ein Gitter
Viel Spaß mit deinen endlosen Schriftrollen !! ^. ^
Da Android Kotlin jetzt offiziell unterstützt, gibt es hier ein Update dafür -
Machen Sie OnScrollListener
und fügen Sie es wie folgt zu Ihrem RecyclerView hinzu
Ein vollständiges Codebeispiel finden Sie in diesem Github-Repo .
quelle
findFirstVisibleItemPosition()
Methode nur mit dem LinearLayoutManager verfügbar ist, kann ich nicht herausfinden, wie sie funktioniert.visibleItemCount = mLayoutManager.getChildCount();
verhält sich using genauso wie usingvisibleItemCount = mRecyclerView.getChildCount();
.int[] firstVisibleItemPositions = new int[yourNumberOfColumns]; pastVisiblesItems = layoutManager.findFirstVisibleItemPositions(firstVisibleItemPositions)[0];
Für diejenigen, die nur benachrichtigt werden möchten, wenn der letzte Artikel vollständig angezeigt wird, können Sie verwenden
View.canScrollVertically()
.Hier ist meine Implementierung:
Hinweis: Sie können verwenden,
recyclerView.getLayoutManager().canScrollVertically()
wenn Sie API <14 unterstützen möchten.quelle
RecyclerView
Sie wieder Glück, denn Sie können einfach eine statische Kopie davon erstellen,View.canScrollVertically()
da die zugehörigen Methoden als öffentlich und nicht als geschützt markiert sindRecyclerView
. Sie können die Erweiterung auch erweiternRecyclerView
,canScrollVertically()
wenn Sie möchten. Eine dritte und einfache Möglichkeit ist das AnrufenrecyclerView.getLayoutManager().canScrollVertically()
. In meiner Antwort bearbeitet.Hier ist ein anderer Ansatz. Es funktioniert mit jedem Layout-Manager.
Für ein detailliertes Verständnis habe ich einen Blog-Beitrag und ein Beispielprojekt geschrieben. Hier finden Sie http://sab99r.com/blog/recyclerview-endless-load-more/
MyAdapter.java
MyActivity.java
quelle
Meine Antwort ist eine modifizierte Version von Noor. Ich ging von einem Ort, den
ListView
ich hatteEndlessScrollListener
(den Sie in vielen Antworten auf SO leicht finden können) zu einem,RecyclerView
also wollteEndlessRecyclScrollListener
ich meinen früheren Hörer einfach aktualisieren.Also hier ist der Code, hoffe es hilft:
quelle
Für mich ist es sehr einfach:
Seien Sie vorsichtig mit asynchronen Jobs: Das Laden von ml muss am Ende der asynchronen Jobs geändert werden. Hoffe es wird hilfreich sein!
quelle
Die meisten Antwort geht davon aus dem
RecyclerView
einem verwendetLinearLayoutManager
, oderGridLayoutManager
, oder sogarStaggeredGridLayoutManager
, oder unter der Annahme , dass das Scrollen vertikal oder horyzontal ist, aber niemand eine völlig generische Antwort geschrieben hat .Die Verwendung des
ViewHolder
Adapters ist eindeutig keine gute Lösung. Ein Adapter kann mehr als 1RecyclerView
verwenden. Es "passt" ihren Inhalt an. Es sollte die Recycler- Ansicht sein (dies ist die eine Klasse, die für das verantwortlich ist, was dem Benutzer aktuell angezeigt wird, und nicht der Adapter, der nur für die Bereitstellung von Inhalten für den Benutzer verantwortlich istRecyclerView
), die Ihr System darüber informieren muss, dass weitere Elemente benötigt werden (an Belastung).Hier ist meine Lösung, die nichts anderes als die abstrahierten Klassen von RecyclerView (RecycerView.LayoutManager und RecycerView.Adapter) verwendet:
quelle
LayoutManagers
einen Moment: Verschieben Sie Ihren Berechnungscode in eine andere scrollListener-Methode - verschieben Sie ihnonScrollStateChanged
stattdessen nachonScrolled
. UndonScrollStateChanged
überprüfen Sie einfach:if(newState == RecyclerView.SCROLL_STATE_IDLE) { // calculation code }
Obwohl die akzeptierte Antwort einwandfrei funktioniert, verwendet die folgende Lösung addOnScrollListener, da setOnScrollListener veraltet ist und die Anzahl der Variablen sowie die if-Bedingungen reduziert.
quelle
Obwohl es so viele Antworten auf die Frage gibt, möchte ich unsere Erfahrungen mit der Erstellung der endlosen Listenansicht teilen. Wir haben kürzlich einen benutzerdefinierten Karussell-Layout-Manager implementiert, der im Zyklus funktionieren kann, indem die Liste unendlich und bis zu einem bestimmten Punkt gescrollt wird. Hier ist eine detaillierte Beschreibung auf GitHub .
Ich schlage vor, dass Sie sich diesen Artikel mit kurzen, aber wertvollen Empfehlungen zum Erstellen benutzerdefinierter LayoutManager ansehen: http://cases.azoft.com/create-custom-layoutmanager-android/
quelle
Mit der Leistung der Kotlin-Erweiterungsfunktionen kann der Code viel eleganter aussehen. Platzieren Sie dies an einer beliebigen Stelle (ich habe es in einer ExtensionFunctions.kt-Datei):
Und dann benutze es so:
Diese Lösung basiert auf der Antwort von Kushal Sharma. Dies ist jedoch etwas besser, weil:
onScrollStateChanged
anstelle vononScroll
. Dies ist besser, daonScroll
es jedes MalonScrollStateChanged
aufgerufen wird, wenn sich in der RecyclerView irgendeine Bewegung befindet, während es nur aufgerufen wird, wenn der Status der RecyclerView geändert wird. DurchonScrollStateChanged
die Verwendung sparen Sie CPU-Zeit und damit Batterie.quelle
SwipeRefreshLayout's setOnRefreshListener the addOnScrolledToEnd is not working
private innere Klasse PullToRefresh gezogen habe: SwipeRefreshLayout.OnRefreshListener {Spaß überschreiben onRefresh () {pbViewMore !! ! .isRefreshing = false}}So mache ich es, einfach und kurz:
quelle
OK, ich habe es mit der onBindViewHolder- Methode von RecyclerView.Adapter gemacht.
Adapter:
Fragment (oder Aktivität) :
quelle
onBindViewHolder()
. Sie funktioniert wie ein Zauber. Die Implementierung ist im Vergleich zum Scroll-Listener winzig und einfacher zu bedienen.Meine Art, ein Ladeereignis zu erkennen, besteht nicht darin, einen Bildlauf zu erkennen, sondern zu überwachen, ob die letzte Ansicht angehängt wurde. Wenn die letzte Ansicht angehängt wurde, betrachte ich sie als Zeitpunkt, um mehr Inhalte zu laden.
quelle
Ich würde versuchen, die verwendete
LayoutManager
(z. B.LinearLayoutManager
) und überschreibendescrollVerticallyBy()
Methode zu erweitern. Zuerst würde ichsuper
zuerst aufrufen und dann den zurückgegebenen ganzzahligen Wert überprüfen. Wenn der Wert gleich ist,0
wird ein unterer oder ein oberer Rand erreicht. Dann würde ich diefindLastVisibleItemPosition()
Methode verwenden, um herauszufinden, welche Grenze erreicht ist, und bei Bedarf weitere Daten laden. Nur eine Idee.Darüber hinaus können Sie sogar Ihren Wert von dieser Methode zurückgeben, indem Sie ein Überschreiben und das Anzeigen der Anzeige "Laden" zulassen.
quelle
quelle
onScrollStateChanged()
funktioniert nicht, da es nur aufgerufen wird, wenn Sie den Status des Bildlaufs ändern und nicht, während Sie scrollen. Sie müssen dieonScrolled()
Methode verwenden.Mit dieser Logik in der
onBindViewHolder
Methode meinerRecyclerView.Adapter
Klasse habe ich eine Implementierung vom Typ "Unendlicher Bildlauf" erreicht .Wenn der RecyclerView mit diesem Code zum letzten Element gelangt, werden die aktuelle Seite und die Rückrufe auf einer Schnittstelle erhöht, die für das Laden weiterer Daten aus der API und das Hinzufügen der neuen Ergebnisse zum Adapter verantwortlich ist.
Ich kann ein vollständigeres Beispiel posten, wenn dies nicht klar ist.
quelle
Für Leute, die StaggeredGridLayoutManager verwenden , ist hier meine Implementierung, es funktioniert für mich.
quelle
Es gibt eine einfach zu bedienende Bibliothek für diesen Namen Paginate . Unterstützt sowohl ListView als auch RecyclerView (LinearLayout, GridLayout und StaggeredGridLayout).
Hier ist der Link zum Projekt auf Github
quelle
Erstellen Sie eine abstrakte Klasse und erweitern Sie RecyclerView.OnScrollListener
Fügen Sie in Aktivität (oder Fragment) addOnScrollListener zu recyclerView hinzu
quelle
Ich habe ein ziemlich detailliertes Beispiel für die Paginierung mit einem RecyclerView. Auf einer hohen Ebene habe ich eine Menge PAGE_SIZE, sagen wir 30. Also fordere ich 30 Artikel an und wenn ich 30 zurück bekomme, fordere ich die nächste Seite an. Wenn ich weniger als 30 Elemente erhalte, markiere ich eine Variable, um anzuzeigen, dass die letzte Seite erreicht wurde, und fordere dann keine weiteren Seiten mehr an. Probieren Sie es aus und lassen Sie mich wissen, was Sie denken.
https://medium.com/@etiennelawlor/pagination-with-recyclerview-1cb7e66a502b
quelle
Hier lautet meine Lösung mit AsyncListUtil im Web: Beachten Sie, dass diese Klasse zum Laden der Daten einen einzelnen Thread verwendet, sodass Daten vom sekundären Speicher wie der Festplatte, jedoch nicht vom Netzwerk geladen werden können. Aber ich benutze Odata, um die Daten zu lesen und gut zu funktionieren. Ich vermisse in meinem Beispiel Datenentitäten und Netzwerkmethoden. Ich füge nur den Beispieladapter hinzu.
quelle
@kushal @abdulaziz
Warum nicht stattdessen diese Logik verwenden?
quelle
end_of_list
Bedingung nur einmal aufgerufen wird. Das Flag_isLastItem
ist eine globale Variable in der Aktivität mit dem Standardwertfalse
. Ich habe eine Hintergrundaufgabe ausgeführt, nachdem ich das Ende der Liste erkannt, die nächste Seite abgerufen, den Adapter über das neue Dataset benachrichtigt und schließlich wieder_isLastItem
auf false gesetzt habe.Versuchen Sie es unten:
quelle
LoadMoreRecyclerView
WrapperLinearLayout
// Füge es in XML wie hinzu
OnCreate oder onViewCreated
Rufen Sie Ihren Service an
quelle
Es ist auch möglich, ohne den Scroll-Listener zu implementieren, wobei nur die reine Logik des Datenmodells verwendet wird. Die Bildlaufansicht erfordert das Abrufen von Elementen nach Position sowie die maximale Anzahl von Elementen. Das Modell kann über die Hintergrundlogik verfügen, um die erforderlichen Elemente nicht einzeln, sondern in Blöcken abzurufen, und dies im Hintergrundthread, um die Ansicht zu benachrichtigen, wenn die Daten bereit sind.
Dieser Ansatz ermöglicht es, dass die Abrufwarteschlange, die zuletzt angeforderte (also derzeit sichtbare) Elemente gegenüber älteren (höchstwahrscheinlich bereits weggescrollten) Übermittlungen bevorzugt, die Anzahl der zu verwendenden parallelen Threads und dergleichen steuert. Den vollständigen Quellcode für diesen Ansatz (Demo-App und wiederverwendbare Bibliothek) finden Sie hier .
quelle
Es gibt eine Methode
public void setOnScrollListener (RecyclerView.OnScrollListener listener)
in https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#setOnScrollListener%28android.support.v7.widget.RecyclerView.OnScrollListener%29 . Verwende dasBEARBEITEN:
Überschreiben Sie die
onScrollStateChanged
Methode innerhalb vononScrollListener
und tun Sie diesquelle
onScrollStateChanged
onScrollStateChanged
funktioniert nicht, da es nur aufgerufen wird, wenn Sie den Status des Bildlaufs ändern und nicht, während Sie scrollen.onScrollStateChanged
festgestellt werden, dass der Benutzer zum letzten Element scrollt?Überprüfen Sie, ob alles im Detail erklärt wird: Paginierung mit RecyclerView Von A bis Z.
loadMoreItems ():
in MyAdapter:
quelle
Keine dieser Antworten berücksichtigt, ob die Liste zu klein ist oder nicht.
Hier ist ein Code, den ich verwendet habe und der in RecycleViews in beide Richtungen funktioniert.
quelle
Ich lasse dich meine Annäherung. Funktioniert gut für mich.
Ich hoffe es hilft dir.
quelle
Diese Lösung funktioniert perfekt für mich.
quelle