Jednym z rozwiązań jest wdrożenie OnScrollListeneri wprowadzenie zmian (takich jak dodawanie elementów itp.) ListAdapterW dogodnym stanie w tej onScrollmetodzie.
Poniżej ListActivityprzedstawiono listę liczb całkowitych, zaczynając od 40, dodając elementy, gdy użytkownik przewija do końca listy.
Oczywiście powinieneś używać osobnych wątków do długotrwałych działań (takich jak ładowanie danych internetowych) i możesz chcieć wskazać postęp w ostatnim elemencie listy (tak jak robią to aplikacje market lub Gmail).
huh, czy nie spowodowałoby to zwiększenia rozmiaru adaptera, gdybyś przestał przewijać na środku ekranu? powinien załadować kolejne 10 dopiero po osiągnięciu dolnej listy.
Matthias,
9
Zauważam wiele takich przykładów za pomocą BaseAdapter. Chciałem wspomnieć, że jeśli korzystasz z bazy danych, spróbuj użyć SimpleCursorAdapter. Gdy musisz dodać do listy, zaktualizuj bazę danych, uzyskaj nowy kursor i użyj SimpleCursorAdapter # changeCursor wraz z powiadomieniemDataSetChanged. Nie jest wymagane żadne podklasowanie i działa ono lepiej niż BaseAdapter (ponownie, tylko jeśli używasz bazy danych).
nawias
1
Po wywołaniu powiadomieniaDataSetChanged (), znajdzie się na górze listy, jak mogę temu zapobiec?
losowanie
2
Uwaga - zastosowałem to podejście, ale musiałem dodać opcję sprawdzania, gdy parametr visibleCount wynosi 0. Dla każdej listy otrzymuję jedno wywołanie zwrotne do onScroll, gdzie firstVisible, visibleCount i totalCount mają wartość 0, co technicznie spełnia warunek, ale nie jest kiedy chcę załadować więcej.
Eric Mill
5
Innym problemem związanym z tym kodem jest to, że warunek firstVisible + visibleCount >= totalCountjest spełniony wiele razy przy wielu wywołaniach do nasłuchiwania. Jeśli funkcja ładowania więcej jest żądaniem internetowym (najprawdopodobniej będzie), dodaj kolejne sprawdzenie, czy żądanie trwa, czy nie. Z drugiej strony sprawdź, czy totalCount nie jest równy Poprzedniej sumie, ponieważ nie potrzebujemy wielu żądań dla tej samej liczby pozycji na liście.
Subin Sebastian
94
Chciałem tylko udostępnić rozwiązanie, którego użyłem w mojej aplikacji.
Opiera się również na OnScrollListenerinterfejsie, ale zauważyłem, że ma on znacznie lepszą wydajność przewijania na niższych urządzeniach, ponieważ podczas operacji przewijania nie są wykonywane żadne obliczenia widoczne / całkowite zliczanie.
@Overridepublicvoid onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount){//leave this empty}@Overridepublicvoid onScrollStateChanged(AbsListView listView,int scrollState){if(scrollState == SCROLL_STATE_IDLE){if(listView.getLastVisiblePosition()>= listView.getCount()-1- threshold){
currentPage++;//load more list items:
loadElements(currentPage);}}}
gdzie currentPageznajduje się strona źródła danych, które należy dodać do listy, i thresholdliczba elementów listy (liczona od końca), które powinny, jeśli są widoczne, uruchomić proces ładowania. Jeśli ustawisz thresholdsię 0, na przykład, użytkownik musi przejść na samym końcu listy, aby załadować więcej rzeczy.
(opcjonalnie) Jak widać, „ładowanie więcej kontroli” jest wywoływane tylko wtedy, gdy użytkownik przestanie przewijać. Aby poprawić użyteczność, możesz napompować i dodać wskaźnik ładowania na końcu listy za pośrednictwem listView.addFooterView(yourFooterView). Jeden przykład takiego widoku stopki:
Próbowałem tego, ale to nie działa dla ListFragment. Jak można go używać w ListFragment.
zeeshan
Cóż, używam go ListFragmentrównież bez żadnych problemów - wystarczy wykonać każdy z powyższych kroków, a wszystko będzie dobrze;) Czy możesz podać jakieś komunikaty o błędach?
saschoar
To, co mogło być pominięte, zostało wyjaśnione w tej odpowiedzi SO: stackoverflow.com/a/6357957/1478093 -getListView().setOnScrollListener(this)
TBieniek
7
Uwaga: dodawanie i usuwanie stopki w widoku listy jest problematyczne (stopka nie wyświetla się, jeśli setAdapter jest wywoływany przed dodaniem stopki), skończyłem modyfikując widoczność widoku stopki bezpośrednio bez jej usuwania.
dvd,
Co należy dodać w loadElements (currentPage) ??? Mam na myśli, czy nazywam moją AsyncTask lub wątek?
android_developer
20
Koniec listy można wykryć przy pomocy onScrollListener , działający kod przedstawiono poniżej:
publicView getView(int pos,View v,ViewGroup p){if(pos==getCount()-1){
addMoreData();//should be asynctask or thread}return view;}
Pamiętaj, że ta metoda będzie wywoływana wiele razy, więc musisz dodać kolejny warunek, aby zablokować wiele wywołań addMoreData().
Po dodaniu wszystkich elementów do listy należy wywołać powiadomienie DataSetChanged () wewnątrz adaptera, aby zaktualizować widok (powinien być uruchamiany w wątku interfejsu użytkownika - runOnUiThread )
Złą praktyką jest robienie innych rzeczy niż powrót do widoku getView. Na przykład nie masz gwarancji, że posużytkownik wyświetli. Może to być po prostu pomiar ListView.
Thomas Ahle,
Chcę załadować więcej elementów po przewinięciu 10 elementów. ale zauważam, że ładowanie zaczyna się, zanim 10 element będzie widoczny, oznacza 9 element. Więc jak to zatrzymać?
Wykorzystuje to, Volley HTTP libraryco sprawia, że tworzenie sieci dla aplikacji na Androida jest łatwiejsze i, co najważniejsze, szybsze. Siatkówka jest dostępna za pośrednictwem otwartego repozytorium AOSP.
Podany kod pokazuje:
ListView, który jest wypełniany przez paginowane żądania HTTP.
Zastosowanie NetworkImageView.
Pagodowanie „Endless” ListView z możliwością odczytu z wyprzedzeniem.
Może trochę się spóźnić, ale w moim przypadku bardzo przydatne okazało się następujące rozwiązanie. W ten sposób wszystko, co musisz zrobić, to dodać do ListView a Footeri stworzyć dla niego addOnLayoutChangeListener.
ListView listView1 =(ListView) v.findViewById(R.id.dialogsList);// Your listViewView loadMoreView = getActivity().getLayoutInflater().inflate(R.layout.list_load_more,null);// Getting your layout of FooterView, which will always be at the bottom of your listview. E.g. you may place on it the ProgressBar or leave it empty-layout.
listView1.addFooterView(loadMoreView);// Adding your View to your listview ...
loadMoreView.addOnLayoutChangeListener(newView.OnLayoutChangeListener(){@Overridepublicvoid onLayoutChange(View v,int left,int top,int right,int bottom,int oldLeft,int oldTop,int oldRight,int oldBottom){Log.d("Hey!","Your list has reached bottom");}});
To wydarzenie jest uruchamiane raz, gdy stopka staje się widoczna i działa jak urok.
Kluczem do tego problemu jest wykrycie zdarzenia ładowania obciążenia, uruchomienie żądania asynchronicznego danych, a następnie zaktualizowanie listy. Potrzebny jest również adapter ze wskaźnikiem obciążenia i innymi dekoratorami. W rzeczywistości problem jest bardzo skomplikowany w niektórych przypadkach narożnych. Tylko OnScrollListenerrealizacja nie wystarczy, bo czasami elementy nie wypełnia ekranu.
Napisałem osobisty pakiet, który obsługuje nieskończoną listę RecyclerView, a także zapewnia implementację modułu ładującego asynchron, AutoPagerFragmentktóry bardzo ułatwia pobieranie danych ze źródła wielostronicowego. Może załadować dowolną stronę RecyclerViewna niestandardowe zdarzenie, nie tylko następną stronę.
Pracowałem w innym rozwiązaniu bardzo podobnym do tego, ale używam a, footerViewaby dać użytkownikowi możliwość pobrania większej liczby elementów, klikając przycisk footerView, używam „menu” pokazanego powyżej ListViewi na dole widok rodzica, to „menu” ukrywa dolną część ListView, więc gdy listViewprzewijane menu zniknie, a gdy stan przewijania jest bezczynny, menu pojawi się ponownie, ale gdy użytkownik przewinie do końca listView, „pytam”, aby wiedzieć, czy footerVieww takim przypadku jest pokazane, menu nie pojawia się, a użytkownik może zobaczyć, footerViewaby załadować więcej treści. Oto kod:
Wiem, że to stare pytanie, a świat Androida przeszedł w większości na RecyclerViews, ale dla wszystkich zainteresowanych ta biblioteka może być bardzo interesująca.
Wykorzystuje BaseAdapter używany z ListView do wykrywania, kiedy lista została przewinięta do ostatniego elementu lub kiedy jest przewijana od ostatniego elementu.
Zawiera przykładowy projekt (zaledwie 100 wierszy kodu działania), którego można użyć, aby szybko zrozumieć, jak to działa.
loadMorePozycja jest przycisk lub inny element interfejsu użytkownika, które można kliknąć, aby pobrać więcej danych z adresu URL. Po umieszczeniu zgodnie z opisem w kodzie adapter dokładnie wie, kiedy pokazać ten przycisk, a kiedy go wyłączyć. Po prostu utwórz przycisk w swoim pliku XML i umieść go tak, jak pokazano w powyższym kodzie adaptera.
Odpowiedzi:
Jednym z rozwiązań jest wdrożenie
OnScrollListener
i wprowadzenie zmian (takich jak dodawanie elementów itp.)ListAdapter
W dogodnym stanie w tejonScroll
metodzie.Poniżej
ListActivity
przedstawiono listę liczb całkowitych, zaczynając od 40, dodając elementy, gdy użytkownik przewija do końca listy.Oczywiście powinieneś używać osobnych wątków do długotrwałych działań (takich jak ładowanie danych internetowych) i możesz chcieć wskazać postęp w ostatnim elemencie listy (tak jak robią to aplikacje market lub Gmail).
źródło
firstVisible + visibleCount >= totalCount
jest spełniony wiele razy przy wielu wywołaniach do nasłuchiwania. Jeśli funkcja ładowania więcej jest żądaniem internetowym (najprawdopodobniej będzie), dodaj kolejne sprawdzenie, czy żądanie trwa, czy nie. Z drugiej strony sprawdź, czy totalCount nie jest równy Poprzedniej sumie, ponieważ nie potrzebujemy wielu żądań dla tej samej liczby pozycji na liście.Chciałem tylko udostępnić rozwiązanie, którego użyłem w mojej aplikacji.
Opiera się również na
OnScrollListener
interfejsie, ale zauważyłem, że ma on znacznie lepszą wydajność przewijania na niższych urządzeniach, ponieważ podczas operacji przewijania nie są wykonywane żadne obliczenia widoczne / całkowite zliczanie.ListFragment
lubListActivity
wdrożyćOnScrollListener
Dodaj następujące metody do tej klasy:
gdzie
currentPage
znajduje się strona źródła danych, które należy dodać do listy, ithreshold
liczba elementów listy (liczona od końca), które powinny, jeśli są widoczne, uruchomić proces ładowania. Jeśli ustawiszthreshold
się0
, na przykład, użytkownik musi przejść na samym końcu listy, aby załadować więcej rzeczy.(opcjonalnie) Jak widać, „ładowanie więcej kontroli” jest wywoływane tylko wtedy, gdy użytkownik przestanie przewijać. Aby poprawić użyteczność, możesz napompować i dodać wskaźnik ładowania na końcu listy za pośrednictwem
listView.addFooterView(yourFooterView)
. Jeden przykład takiego widoku stopki:(opcjonalnie) Na koniec usuń ten wskaźnik ładowania, dzwoniąc,
listView.removeFooterView(yourFooterView)
jeśli nie ma już więcej elementów lub stron.źródło
ListFragment
również bez żadnych problemów - wystarczy wykonać każdy z powyższych kroków, a wszystko będzie dobrze;) Czy możesz podać jakieś komunikaty o błędach?getListView().setOnScrollListener(this)
Koniec listy można wykryć przy pomocy onScrollListener , działający kod przedstawiono poniżej:
Innym sposobem na to (wewnętrzny adapter) jest:
Pamiętaj, że ta metoda będzie wywoływana wiele razy, więc musisz dodać kolejny warunek, aby zablokować wiele wywołań
addMoreData()
.Po dodaniu wszystkich elementów do listy należy wywołać powiadomienie DataSetChanged () wewnątrz adaptera, aby zaktualizować widok (powinien być uruchamiany w wątku interfejsu użytkownika - runOnUiThread )
źródło
getView
. Na przykład nie masz gwarancji, żepos
użytkownik wyświetli. Może to być po prostu pomiar ListView.W
Ognyan Bankov GitHub
znalazłem proste i działające rozwiązanie!Wykorzystuje to,
Volley HTTP library
co sprawia, że tworzenie sieci dla aplikacji na Androida jest łatwiejsze i, co najważniejsze, szybsze. Siatkówka jest dostępna za pośrednictwem otwartego repozytorium AOSP.Podany kod pokazuje:
Aby zachować spójność w przyszłości, rozwidliłem repozytorium Bankowa .
źródło
Oto rozwiązanie, które ułatwia wyświetlanie widoku ładowania na końcu ListView podczas ładowania.
Możesz zobaczyć zajęcia tutaj:
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - Pomocnik umożliwiający korzystanie z funkcje bez rozszerzania z SimpleListViewWithLoadingIndicator.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java - Słuchacz, który rozpoczyna ładowanie danych, gdy użytkownik zbliża się do dolnej części ListView.
https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - The EndlessListView. Możesz użyć tej klasy bezpośrednio lub ją rozszerzyć.
źródło
Może trochę się spóźnić, ale w moim przypadku bardzo przydatne okazało się następujące rozwiązanie. W ten sposób wszystko, co musisz zrobić, to dodać do ListView a
Footer
i stworzyć dla niegoaddOnLayoutChangeListener
.http://developer.android.com/reference/android/widget/ListView.html#addFooterView(android.view.View)
Na przykład:
To wydarzenie jest uruchamiane raz, gdy stopka staje się widoczna i działa jak urok.
źródło
Kluczem do tego problemu jest wykrycie zdarzenia ładowania obciążenia, uruchomienie żądania asynchronicznego danych, a następnie zaktualizowanie listy. Potrzebny jest również adapter ze wskaźnikiem obciążenia i innymi dekoratorami. W rzeczywistości problem jest bardzo skomplikowany w niektórych przypadkach narożnych. Tylko
OnScrollListener
realizacja nie wystarczy, bo czasami elementy nie wypełnia ekranu.Napisałem osobisty pakiet, który obsługuje nieskończoną listę
RecyclerView
, a także zapewnia implementację modułu ładującego asynchron,AutoPagerFragment
który bardzo ułatwia pobieranie danych ze źródła wielostronicowego. Może załadować dowolną stronęRecyclerView
na niestandardowe zdarzenie, nie tylko następną stronę.Oto adres: https://github.com/SphiaTower/AutoPagerRecyclerManager
źródło
Najlepsze rozwiązanie, jakie do tej pory widziałem, znajduje się w bibliotece FastAdapter dla widoków recyklerów. Ma
EndlessRecyclerOnScrollListener
.Oto przykładowe użycie: EndlessScrollListActivity
Kiedyś użyłem go do nieskończonej przewijanej listy, zdałem sobie sprawę, że konfiguracja jest bardzo solidna. Zdecydowanie polecam.
źródło
Pracowałem w innym rozwiązaniu bardzo podobnym do tego, ale używam a,
footerView
aby dać użytkownikowi możliwość pobrania większej liczby elementów, klikając przyciskfooterView
, używam „menu” pokazanego powyżejListView
i na dole widok rodzica, to „menu” ukrywa dolną częśćListView
, więc gdylistView
przewijane menu zniknie, a gdy stan przewijania jest bezczynny, menu pojawi się ponownie, ale gdy użytkownik przewinie do końcalistView
, „pytam”, aby wiedzieć, czyfooterView
w takim przypadku jest pokazane, menu nie pojawia się, a użytkownik może zobaczyć,footerView
aby załadować więcej treści. Oto kod:Pozdrowienia.
źródło
Wiem, że to stare pytanie, a świat Androida przeszedł w większości na RecyclerViews, ale dla wszystkich zainteresowanych ta biblioteka może być bardzo interesująca.
Wykorzystuje BaseAdapter używany z ListView do wykrywania, kiedy lista została przewinięta do ostatniego elementu lub kiedy jest przewijana od ostatniego elementu.
Zawiera przykładowy projekt (zaledwie 100 wierszy kodu działania), którego można użyć, aby szybko zrozumieć, jak to działa.
Proste użycie:
Adapter do przechowywania obiektów Boy wyglądałby następująco:
Zwróć uwagę, w jaki sposób metoda getView BoysAdapter zwraca wywołanie do metody nadklasy EndlessAdapter
getView
. Jest to w 100% niezbędne.Teraz, aby utworzyć adapter, wykonaj:
loadMore
Pozycja jest przycisk lub inny element interfejsu użytkownika, które można kliknąć, aby pobrać więcej danych z adresu URL. Po umieszczeniu zgodnie z opisem w kodzie adapter dokładnie wie, kiedy pokazać ten przycisk, a kiedy go wyłączyć. Po prostu utwórz przycisk w swoim pliku XML i umieść go tak, jak pokazano w powyższym kodzie adaptera.Cieszyć się.
źródło