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?

Author: Tshepang, 2009-07-04

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).

 267
Author: Josef Pfleger,
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.

  1. niech twój ListFragment lub ListActivity zaimplementuje OnScrollListener
  2. 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, a threshold jest liczbą elementów listy (liczonych od końca), która powinna, jeśli jest widoczna, uruchomić proces ładowania. Jeśli na przykład ustawisz threshold na 0, użytkownik musi przewijać na sam koniec listy, aby załadować więcej pozycji.

  3. (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>
    
  4. (opcjonalne) na koniec usuń ten wskaźnik ładowania, wywołując listView.removeFooterView(yourFooterView), jeśli nie ma więcej elementów lub stron.

 92
Author: saschoar,
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 )

 20
Author: Dariusz Bacinski,
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:

  1. ListView wypełniany przez zapytania zawierające strony HTTP.
  2. użycie NetworkImageView.
  3. "nieskończona" paginacja ListView z możliwością odczytu z wyprzedzeniem.

na przyszłość consistence iforked Bankov ' s repo .

 4
Author: oikonomopo,
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.

 2
Author: Fernando Camargo,
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.

 1
Author: tehcpu,
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

 0
Author: ProtossShuttle,
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.

 0
Author: Shubham Chaudhary,
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:

Pozdrawiam.
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) {

    }
});
 0
Author: pabloverd,
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