Android Endless List
Jak mogę utworzyć listę, w której po dotarciu do końca listy otrzymuję powiadomienie, aby móc załadować więcej pozycji?
9 answers
Jednym z rozwiązań jest wdrożenie OnScrollListener
i wprowadzać zmiany (np. dodawanie elementów itp.) do ListAdapter
w dogodnym stanie w swojej metodzie onScroll
.
Poniżej ListActivity
pokazuje listę liczb całkowitych, zaczynając od 40, dodając elementy, gdy użytkownik przewija się na koniec listy.
public class Test extends ListActivity implements OnScrollListener {
Aleph0 adapter = new Aleph0();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(adapter);
getListView().setOnScrollListener(this);
}
public void onScroll(AbsListView view,
int firstVisible, int visibleCount, int totalCount) {
boolean loadMore = /* maybe add a padding */
firstVisible + visibleCount >= totalCount;
if(loadMore) {
adapter.count += visibleCount; // or any other amount
adapter.notifyDataSetChanged();
}
}
public void onScrollStateChanged(AbsListView v, int s) { }
class Aleph0 extends BaseAdapter {
int count = 40; /* starting amount */
public int getCount() { return count; }
public Object getItem(int pos) { return pos; }
public long getItemId(int pos) { return pos; }
public View getView(int pos, View v, ViewGroup p) {
TextView view = new TextView(Test.this);
view.setText("entry " + pos);
return view;
}
}
}
Powinieneś oczywiście używać oddzielnych wątków do długich działań (takich jak ładowanie danych internetowych) i być może chcesz wskazać postęp w ostatniej pozycji listy (jak aplikacje market lub Gmail do).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-08 19:58:24
Chciałem tylko dodać rozwiązanie, którego użyłem dla mojej aplikacji.
Jest również oparty na interfejsie OnScrollListener
, ale stwierdziłem, że ma znacznie lepszą wydajność przewijania na urządzeniach low-end, ponieważ żadne z widocznych / całkowitych obliczeń nie są wykonywane podczas operacji przewijania.
- niech twój
ListFragment
lubListActivity
zaimplementujeOnScrollListener
-
Dodaj następujące metody do tej klasy:
@Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //leave this empty } @Override public void 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
currentPage
jest stroną twojego źródła danych, która powinna być dodana do listy, athreshold
jest liczbą elementów listy (liczonych od końca), która powinna, jeśli jest widoczna, uruchomić proces ładowania. Jeśli na przykład ustawiszthreshold
na0
, użytkownik musi przewijać na sam koniec listy, aby załadować więcej pozycji. -
(opcjonalne) Jak widać, "load-more check" jest wywoływany tylko wtedy, gdy użytkownik przestaje przewijać. Aby poprawić użyteczność, możesz nadmuchać i dodać wskaźnik ładowania na końcu listy za pomocą
listView.addFooterView(yourFooterView)
. Jeden przykład takiego widoku stopki:<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/footer_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" > <ProgressBar android:id="@+id/progressBar1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_gravity="center_vertical" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toRightOf="@+id/progressBar1" android:padding="5dp" android:text="@string/loading_text" /> </RelativeLayout>
(opcjonalne) na koniec usuń ten wskaźnik ładowania, wywołując
listView.removeFooterView(yourFooterView)
, jeśli nie ma więcej elementów lub stron.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-08 15:18:26
Możesz wykryć koniec listy za pomocą onscrollistener , kod roboczy jest przedstawiony poniżej:
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (view.getAdapter() != null && ((firstVisibleItem + visibleItemCount) >= totalItemCount) && totalItemCount != mPrevTotalItemCount) {
Log.v(TAG, "onListEnd, extending list");
mPrevTotalItemCount = totalItemCount;
mAdapter.addMoreData();
}
}
Inny sposób na to (wewnętrzny adapter) jest następujący:
public View 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, wywołaj notifyDataSetChanged () wewnątrz Twojego adaptera, aby zaktualizować widok (powinien być uruchomiony w wątku UI - runOnUiThread )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-08 18:02:57
At Ognyan Bankov GitHub
znalazłem proste i działające rozwiązanie!
Korzysta zVolley HTTP library
dzięki temu Sieć dla aplikacji na Androida jest łatwiejsza, a co najważniejsze-szybsza. Volley jest dostępny za pośrednictwem otwartego repozytorium AOSP.
Podany kod pokazuje:
- ListView wypełniany przez zapytania zawierające strony HTTP.
- użycie NetworkImageView.
- "nieskończona" paginacja ListView z możliwością odczytu z wyprzedzeniem.
na przyszłość consistence iforked Bankov ' s repo .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-18 14:59:34
Oto rozwiązanie, które ułatwia wyświetlanie widoku ładowania na końcu widoku listy podczas ładowania.
Możesz zobaczyć klasy tutaj:
Https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - Helper umożliwiający korzystanie z funkcji bez rozciągania się od 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 ma dotrzeć do dna ListView.
Https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java / Align = "Left" / Możesz użyć tej klasy bezpośrednio lub rozszerzyć z niej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-17 14:03:08
Może być trochę późno, ale poniższe rozwiązanie stało się bardzo przydatne w moim przypadku.
W pewnym sensie wystarczy dodać do listy Footer
i utworzyć dla niej addOnLayoutChangeListener
.
Http://developer.android.com/reference/android/widget/ListView.html#addFooterView(android.view.View)
Na przykład:
ListView listView1 = (ListView) v.findViewById(R.id.dialogsList); // Your listView
View 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(new View.OnLayoutChangeListener() {
@Override
public void 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 zdarzenie zostanie wywołane raz, gdy stopka stanie się widoczna i będzie działać jak urok.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-10 13:25:46
Kluczem tego problemu jest wykrycie zdarzenia load-more, uruchomienie asynchronicznego żądania danych, a następnie Aktualizacja listy. Potrzebny jest również adapter ze wskaźnikiem załadunku i innymi dekoratorami. W rzeczywistości problem jest bardzo skomplikowany w niektórych przypadkach narożnych. Sama implementacja OnScrollListener
nie wystarczy, ponieważ czasami elementy nie wypełniają ekranu.
Napisałem osobisty pakiet, który obsługuje nieskończoną listę dla RecyclerView
, a także zapewnia implementację asynchronicznego loadera AutoPagerFragment
, który ułatwia pobieranie danych ze źródła wielostronicowego. Może załadować dowolną stronę do RecyclerView
w zdarzeniu niestandardowym, nie tylko na następnej stronie.
Oto adres: https://github.com/SphiaTower/AutoPagerRecyclerManager
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-15 10:19:24
Najlepsze rozwiązanie do tej pory, że widziałem jest w fastadapter biblioteka dla recycler widoki. Posiada EndlessRecyclerOnScrollListener
.
Oto przykład użycia: EndlessScrollListActivity
Kiedy użyłem go do niekończącej się listy przewijania, zdałem sobie sprawę, że konfiguracja jest bardzo solidna. Zdecydowanie polecam.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-01 10:42:31
Pracowałem w innym rozwiązaniu bardzo podobnym do tego, ale używam footerView
aby dać użytkownikowi możliwość pobrania większej ilości elementów klikając footerView
, używam "menu", które jest pokazane powyżej ListView
i w dolnej części widoku nadrzędnego, to "menu" ukrywa dół ListView
, tak więc, gdy listView
jest przewijanie menu znikają i gdy stan przewijania jest bezczynny, menu pojawia się ponownie, ale gdy użytkownik przewija się na koniec listView
, "pytam" Czy footerView
jest pokazywany w w takim przypadku menu nie pojawia się, a użytkownik może zobaczyć footerView
, aby załadować więcej treści. Tutaj kod:
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
if(scrollState == SCROLL_STATE_IDLE) {
if(footerView.isShown()) {
bottomView.setVisibility(LinearLayout.INVISIBLE);
} else {
bottomView.setVisibility(LinearLayout.VISIBLE);
} else {
bottomView.setVisibility(LinearLayout.INVISIBLE);
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-17 07:04:56