Chciałbym się zmienić ListView
na RecyclerView
. Chcę używać onScroll
tego OnScrollListener
IN RecyclerView
, aby określić, czy użytkownik przewijane do końca listy.
Skąd mam wiedzieć, czy użytkownik przewija do końca listy, aby móc pobrać nowe dane z usługi REST?
cwac-endless
forListView
.Odpowiedzi:
Dzięki @Kushal i tak to zaimplementowałem
Nie zapomnij dodać
źródło
StaggeredGridLayoutManager
mLayoutManager.findLastCompletelyVisibleItemPosition()==mLayoutManager.getItemCount()-1
findFirstVisibleItemPosition()
nie rozwiązali, powinieneś zmienićRecyclerView.LayoutManager
naLinearLayoutManager
loading = true
ponownego zrobienia ?loading = true
po//Do pagination
części. w przeciwnym razie ten kod zostanie uruchomiony tylko raz i nie będzie można załadować więcej elementów.Utwórz te zmienne.
Ustaw opcję Przewiń, aby wyświetlić widok recyklera.
i dla siatki
Baw się z niekończącymi się zwojami !! ^. ^
Ponieważ Android oficjalnie obsługuje teraz Kotlin, oto aktualizacja tego samego -
Utwórz OnScrollListener
i dodaj go do swojego RecyclerView w ten sposób
Aby uzyskać pełny kod, zachęcamy do zapoznania się z tym repozytorium Github .
źródło
findFirstVisibleItemPosition()
metoda jest dostępna tylko z LinearLayoutManager, nie mogę wymyślić, jak to zrobić.visibleItemCount = mLayoutManager.getChildCount();
zachowuje się tak samo jak używanievisibleItemCount = mRecyclerView.getChildCount();
.int[] firstVisibleItemPositions = new int[yourNumberOfColumns]; pastVisiblesItems = layoutManager.findFirstVisibleItemPositions(firstVisibleItemPositions)[0];
Dla tych, którzy chcą otrzymywać powiadomienia tylko, gdy ostatni element jest całkowicie pokazany, możesz użyć
View.canScrollVertically()
.Oto moja implementacja:
Uwaga: Możesz użyć,
recyclerView.getLayoutManager().canScrollVertically()
jeśli chcesz obsługiwać API <14.źródło
RecyclerView
, będziesz mieć szczęście, ponieważ możesz po prostu zrobić statyczną kopię,View.canScrollVertically()
ponieważ powiązane metody są oznaczone jako publiczne zamiast chronioneRecyclerView
. Jeśli chcesz, możesz także przedłużyćRecyclerView
implementacjęcanScrollVertically()
. Trzecim i prostym sposobem jest zadzwonienierecyclerView.getLayoutManager().canScrollVertically()
. Edytowane w mojej odpowiedzi.Oto inne podejście. Będzie działać z dowolnym menedżerem układu.
Aby uzyskać szczegółowe zrozumienie, napisałem post na blogu i przykładowy projekt: http://sab99r.com/blog/recyclerview-endless-load-more/
MyAdapter.java
MyActivity.java
źródło
Moja odpowiedź to zmodyfikowana wersja Noora. Przeszedłem z miejsca, w
ListView
którym miałemEndlessScrollListener
(który można łatwo znaleźć w wielu odpowiedziach na SO),RecyclerView
więc chciałemEndlessRecyclScrollListener
łatwo zaktualizować mojego poprzedniego słuchacza.Oto kod, mam nadzieję, że pomoże:
źródło
Dla mnie to bardzo proste:
Uważaj na zadania asynchroniczne: ładowanie mL musi zostać zmienione na końcu zadań asynchronicznych. Mam nadzieję, że to będzie pomocne!
źródło
Większość odpowiedzi zakłada, że
RecyclerView
używaLinearLayoutManager
alboGridLayoutManager
, albo nawetStaggeredGridLayoutManager
, albo zakłada, że przewijanie jest pionowe lub poziome, ale nikt nie opublikował całkowicie ogólnej odpowiedzi .Korzystanie z
ViewHolder
adaptera wyraźnie nie jest dobrym rozwiązaniem. Adapter może mieć z niego więcej niż 1RecyclerView
. „Dostosowuje” ich zawartość. Powinien to być widok Recycler View (który jest jedną klasą, która odpowiada za to, co jest obecnie wyświetlane użytkownikowi, a nie adapter, który jest odpowiedzialny tylko za dostarczanie treści doRecyclerView
), który musi powiadomić system, że potrzeba więcej elementów (aby Załaduj).Oto moje rozwiązanie, wykorzystujące wyłącznie abstrakcyjne klasy RecyclerView (RecycerView.LayoutManager i RecycerView.Adapter):
źródło
LayoutManagers
jeden moment: przenieś kod obliczeniowy za pomocą innej metody scrollListener -onScrollStateChanged
zamiast tego przenieś goonScrolled
. IonScrollStateChanged
tylko sprawdź:if(newState == RecyclerView.SCROLL_STATE_IDLE) { // calculation code }
Chociaż zaakceptowana odpowiedź działa idealnie, poniższe rozwiązanie wykorzystuje addOnScrollListener, ponieważ setOnScrollListener jest przestarzały i zmniejsza liczbę zmiennych oraz warunków.
źródło
Chociaż jest tak wiele odpowiedzi na to pytanie, chciałbym podzielić się naszym doświadczeniem w tworzeniu niekończącego się widoku listy. Niedawno wdrożyliśmy niestandardowy Carousel LayoutManager, który może pracować w cyklu, przewijając listę nieskończenie, a nawet do pewnego momentu. Oto szczegółowy opis na GitHub .
Proponuję rzucić okiem na ten artykuł z krótkimi, ale cennymi zaleceniami dotyczącymi tworzenia niestandardowych menedżerów układów: http://cases.azoft.com/create-custom-layoutmanager-android/
źródło
Dzięki mocy funkcji rozszerzających Kotlin kod może wyglądać o wiele bardziej elegancko. Umieść to gdziekolwiek chcesz (mam go w pliku ExtensionFunctions.kt):
A następnie użyj tego w ten sposób:
To rozwiązanie opiera się na odpowiedzi Kushala Sharmy. Jest to jednak nieco lepsze, ponieważ:
onScrollStateChanged
zamiastonScroll
. Jest to lepsze, ponieważonScroll
jest wywoływane za każdym razem, gdy w RecyclerView występuje jakikolwiek ruch, podczas gdyonScrollStateChanged
jest wywoływane tylko wtedy, gdy stan RecyclerView jest zmieniany. KorzystanieonScrollStateChanged
z niego oszczędza czas procesora, aw konsekwencji baterię.źródło
SwipeRefreshLayout's setOnRefreshListener the addOnScrolledToEnd is not working
prywatną klasę wewnętrzną PullToRefresh: SwipeRefreshLayout.OnRefreshListener {przesłonięcie zabawy onRefresh () {pbViewMore !!. Visibility = View.GONE pageCount = 0 courseList.clear () // wywołanie asynctask tutaj srlNoMessageRefreshLayout !!. False isRefef ! .isRefreshing = false}}Tak to robię, proste i krótkie:
źródło
OK, zrobiłem to za pomocą metody onBindViewHolder RecyclerView.Adapter.
Adapter:
Fragment (lub aktywność) :
źródło
onBindViewHolder()
, działa jak urok. Implementacja jest niewielka w porównaniu do detektora przewijania i jest łatwiejsza w użyciu.Moim sposobem na wykrycie zdarzenia ładowania nie jest wykrycie przewijania, ale sprawdzenie, czy ostatni widok został dołączony. Jeśli dołączono ostatni widok, uważam go za czas załadowania większej ilości treści.
źródło
Spróbowałbym rozszerzyć używaną
LayoutManager
(np.LinearLayoutManager
) I przesłonićscrollVerticallyBy()
metodę. Najpierw zadzwoniłbymsuper
pierwszy, a następnie sprawdził zwracaną wartość całkowitą. Jeśli wartość jest równa,0
wówczas zostanie osiągnięta dolna lub górna granica. Następnie użyłbymfindLastVisibleItemPosition()
metody, aby dowiedzieć się, która granica została osiągnięta i w razie potrzeby załadować więcej danych. Po prostu pomysł.Ponadto możesz nawet zwrócić swoją wartość z tej metody, umożliwiając przewinięcie i pokazując wskaźnik „ładowanie”.
źródło
źródło
onScrollStateChanged()
nie będzie działać, ponieważ będzie wywoływany tylko po zmianie stanu przewijania, a nie podczas przewijania. Musisz użyć tejonScrolled()
metody.Osiągnąłem nieskończoną implementację typu przewijania za pomocą tej logiki w
onBindViewHolder
metodzie mojejRecyclerView.Adapter
klasy.Za pomocą tego kodu, gdy RecyclerView dotrze do ostatniego elementu, zwiększa bieżącą stronę i wywołania zwrotne w interfejsie odpowiedzialnym za ładowanie większej ilości danych z interfejsu API i dodawanie nowych wyników do adaptera.
Mogę opublikować pełniejszy przykład, jeśli nie jest to jasne?
źródło
Dla osób, które używają StaggeredGridLayoutManager tutaj jest moja implementacja, działa ona dla mnie.
źródło
Dla tego o nazwie paginate istnieje łatwa w użyciu biblioteka . Obsługuje zarówno ListView, jak i RecyclerView (LinearLayout, GridLayout i StaggeredGridLayout).
Oto link do projektu na Github
źródło
Utwórz klasę abstrakcyjną i rozszerzy RecyclerView.OnScrollListener
w działaniu (lub fragmencie) dodaj addOnScrollListener do recyclinglerView
źródło
Mam dość szczegółowy przykład sposobu paginacji za pomocą RecyclerView. Na wysokim poziomie mam zestaw PAGE_SIZE, powiedzmy 30. Więc proszę o 30 elementów, a jeśli otrzymam 30, to poproszę o następną stronę. Jeśli otrzymam mniej niż 30 elementów, oflaguję zmienną, aby wskazać, że osiągnięto ostatnią stronę, a następnie przestaję prosić o więcej stron. Sprawdź to i daj mi znać, co myślisz.
https://medium.com/@etiennelawlor/pagination-with-recyclerview-1cb7e66a502b
źródło
Tutaj moje rozwiązanie wykorzystujące AsyncListUtil w Internecie mówi: Zauważ, że ta klasa używa jednego wątku do ładowania danych, więc nadaje się do ładowania danych z pamięci dodatkowej, takiej jak dysk, ale nie z sieci. ale używam odata do odczytu danych i działa dobrze. Brakuje w moich przykładowych jednostkach danych i metodach sieciowych. Podaję tylko przykładowy adapter.
źródło
@kushal @abdulaziz
Dlaczego zamiast tego nie użyć tej logiki?
źródło
end_of_list
warunek zostanie wywołany tylko raz. Flaga_isLastItem
jest zmienną globalną w działaniu, która ma domyślną wartośćfalse
. To, co zrobiłem, to wykonanie zadania w tle po wykryciu końca listy, pobraniu następnej strony, a następnie powiadomieniu adaptera o nowym zestawie danych i wreszcie ustawieniu wartości_isLastItem
false ponownie.Spróbuj poniżej:
źródło
LoadMoreRecyclerView
WrapperLinearLayout
// Dodaj to w formacie XML
OnCreate lub onViewCreated
callYourService
źródło
Możliwe jest również wdrożenie bez detektora przewijania, przy użyciu samej logiki samego modelu danych. Widok przewijania wymaga pobierania elementów według pozycji, a także maksymalnej liczby elementów. Model może mieć logikę tła, aby pobierać potrzebne elementy w porcjach, a nie jeden po drugim, i robić to w wątku tła, powiadamiając widok, gdy dane są gotowe.
Takie podejście pozwala mieć kolejkę pobierania, która woli ostatnio żądane (tak obecnie widoczne) elementy niż starsze (najprawdopodobniej już przewinięte) przesyłki, kontrolować liczbę równoległych wątków do użycia i tym podobne. Pełny kod źródłowy tego podejścia (aplikacja demonstracyjna i biblioteka wielokrotnego użytku) są dostępne tutaj .
źródło
Istnieje metoda
public void setOnScrollListener (RecyclerView.OnScrollListener listener)
w https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#setOnScrollListener%28android.support.v7.widget.RecyclerView.OnScrollListener%29 . Użyć tegoEDYTOWAĆ:
Zastąp
onScrollStateChanged
metodę wewnątrzonScrollListener
i zrób toźródło
onScrollStateChanged
onScrollStateChanged
nie będzie działać, ponieważ będzie wywoływany tylko po zmianie stanu przewijania, a nie podczas przewijania.onScrollStateChanged
ustalić, czy użytkownik przewija do ostatniego elementu?Sprawdź, czy wszystko zostało szczegółowo wyjaśnione: paginacja przy użyciu RecyclerView od A do Z
loadMoreItems ():
w MyAdapter:
źródło
Żadna z tych odpowiedzi nie bierze pod uwagę, jeśli lista jest zbyt mała, czy nie.
Oto fragment kodu, którego używałem, który działa w RecycleViews w obu kierunkach.
źródło
Pozwalam ci moje zbliżenie. Działa dobrze dla mnie.
Mam nadzieję, że Ci to pomoże.
źródło
To rozwiązanie działa dla mnie idealnie.
źródło