Lista interminable de Android

9 minutos de lectura

Lista interminable de Android
isaac waller

¿Cómo puedo crear una lista en la que, cuando llegue al final de la lista, se me notifique para que pueda cargar más elementos?

  • Recomiendo EndlessAdapter de CommonWare: github.com/commonsguy/cwac-endless. Lo encontré a partir de esta respuesta a otra pregunta: stackoverflow.com/questions/4667064/….

    – Tyler Collier

    7 de junio de 2011 a las 5:25

  • Necesito lo mismo… ¿alguien puede ayudarme?…stackoverflow.com/questions/28122304/…

    usuario4050065

    30 de enero de 2015 a las 4:00

1646970069 782 Lista interminable de Android
Josef Pfleger

Una solución es implementar un OnScrollListener y hacer cambios (como agregar elementos, etc.) al ListAdapter en un estado conveniente en su onScroll método.

La siguiente ListActivity muestra una lista de números enteros, comenzando con 40, agregando elementos cuando el usuario se desplaza hasta el final de la lista.

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;
        }
    }
}

Obviamente, debe usar subprocesos separados para acciones de ejecución prolongada (como cargar datos web) y es posible que desee indicar el progreso en el último elemento de la lista (como lo hacen las aplicaciones Market o Gmail).

  • eh, ¿no provocaría esto que aumentara el tamaño del adaptador si dejaras de desplazarte en el medio de la pantalla? solo debería cargar los siguientes 10 cuando llegue al final de la lista.

    – Matías

    5 de agosto de 2010 a las 10:13

  • Veo muchos ejemplos como este usando BaseAdapter. Quería mencionar que si está usando una base de datos, intente usar un SimpleCursorAdapter. Cuando necesite agregar a la lista, actualice su base de datos, obtenga un nuevo cursor y use SimpleCursorAdapter#changeCursor junto con notificarDataSetChanged. No se requieren subclases y funciona mejor que un BaseAdapter (nuevamente, solo si está usando una base de datos).

    – soporte

    20 de octubre de 2010 a las 18:51

  • Después de llamar a notificarDataSetChanged(), aparecerá en la parte superior de la lista, ¿cómo puedo evitarlo?

    – dibujar

    2 de septiembre de 2011 a las 12:57

  • Una nota: utilicé este enfoque, pero necesitaba agregar una verificación para cuando visibleCount es 0. Para cada lista, recibo una devolución de llamada a onScroll donde firstVisible, visibleCount y totalCount son todos 0, lo que técnicamente cumple con el condicional, pero no es cuando quiero cargar más.

    – Eric Molino

    5 de enero de 2012 a las 22:37

  • Otro problema con este código es que la condición firstVisible + visibleCount >= totalCount se cumple varias veces con múltiples llamadas al oyente. Si la función de cargar más es una solicitud web (lo más probable es que lo sea), agregue otra verificación para ver si la solicitud está en curso o no. Por otro lado, verifique si totalCount no es igual al recuento total anterior, porque no necesitamos múltiples solicitudes para la misma cantidad de elementos en la lista.

    – C–

    24 de agosto de 2012 a las 20:14


Lista interminable de Android
saschoar

Solo quería contribuir con una solución que usé para mi aplicación.

También se basa en la OnScrollListener interfaz, pero descubrí que tiene un rendimiento de desplazamiento mucho mejor en dispositivos de gama baja, ya que ninguno de los cálculos de conteo visible/total se lleva a cabo durante las operaciones de desplazamiento.

  1. Deja que ListFragment o ListActivity implementar OnScrollListener
  2. Agregue los siguientes métodos a esa clase:

    @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);
            }
        }
    }
    

    donde currentPage es la página de su fuente de datos que debe agregarse a su lista, y threshold es el número de elementos de la lista (contados desde el final) que deberían, si están visibles, desencadenar el proceso de carga. si configuras threshold para 0por ejemplo, el usuario tiene que desplazarse hasta el final de la lista para cargar más elementos.

  3. (Opcional) Como puede ver, la “comprobación de carga adicional” solo se activa cuando el usuario deja de desplazarse. Para mejorar la usabilidad, puede inflar y agregar un indicador de carga al final de la lista a través de listView.addFooterView(yourFooterView). Un ejemplo para tal vista de pie de página:

    <?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. (Opcional) Finalmente, elimine ese indicador de carga llamando listView.removeFooterView(yourFooterView) si no hay más elementos o páginas.

  • Intenté esto pero no funciona para ListFragment. ¿Cómo se puede usar en ListFragment.

    – zeeshan

    13 de julio de 2013 a las 15:35

  • Bueno, lo uso con ListFragment también sin ningún problema, solo siga cada uno de los pasos anteriores y estará bien;) ¿O podría proporcionar algún mensaje de error?

    – saschoar

    14/07/2013 a las 21:44


  • Lo que podría haberse perdido se explica en esta respuesta SO: stackoverflow.com/a/6357957/1478093 – getListView().setOnScrollListener(this)

    – Tbieniek

    24 de julio de 2013 a las 9:29


  • nota: agregar y eliminar el pie de página en la vista de lista es problemático (el pie de página no aparece si se llama a setAdapter antes de agregar el pie de página), terminé modificando la visibilidad de la vista del pie de página directamente sin eliminarlo.

    – dvd

    20/10/2013 a las 22:53

  • ¿Qué se debe agregar en loadElements (currentPage)? Quiero decir, ¿llamo a mi AsyncTask o un hilo?

    – desarrollador de Android

    28 de noviembre de 2013 a las 8:19

1646970070 871 Lista interminable de Android
dariusz bacinski

Puede detectar el final de la lista con la ayuda de onScrollListenerel código de trabajo se presenta a continuación:

@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();
    }
}

Otra forma de hacerlo (adaptador interior) es la siguiente:

    public View getView(int pos, View v, ViewGroup p) {
            if(pos==getCount()-1){
                addMoreData(); //should be asynctask or thread
            }
            return view;
    }

Tenga en cuenta que este método se llamará muchas veces, por lo que debe agregar otra condición para bloquear varias llamadas de addMoreData().

Cuando agregue todos los elementos a la lista, llame al notificarDataSetChanged() dentro de su adaptador para actualizar la Vista (debe ejecutarse en el hilo de la interfaz de usuario – runOnUiThread)

  • Es una mala práctica hacer otras cosas además de devolver una vista en getView. Por ejemplo, no se le garantiza que pos es visto por el usuario. Podría ser simplemente cosas de medición de ListView.

    – Tomas Ahle

    13 de agosto de 2011 a las 10:10

  • Quiero cargar más elementos después de desplazar 10 elementos. pero me doy cuenta de que la carga comienza antes de que el décimo elemento sea visible en el noveno elemento. Entonces, ¿cómo detener esto?

    – Atul Bhardwaj

    31 de octubre de 2012 a las 6:44


Lista interminable de Android
oikonomopo

En Ognyan Bankov GitHub ¡Encontré una solución simple y funcional!

Hace uso de la Volley HTTP library eso hace que la creación de redes para aplicaciones de Android sea más fácil y, lo que es más importante, más rápida. Volley está disponible a través del repositorio abierto de AOSP.

El código dado demuestra:

  1. ListView que se completa con solicitudes paginadas HTTP.
  2. Uso de NetworkImageView.
  3. Paginación ListView “sin fin” con lectura anticipada.

Para futura consistencia i repo bifurcado de Bankov.

1646970071 964 Lista interminable de Android
fernando camargo

Aquí hay una solución que también facilita mostrar una vista de carga al final de ListView mientras se está cargando.

Puedes ver las clases aquí:

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java
– Ayudante para hacer posible el uso de las funciones sin extender desde SimpleListViewWithLoadingIndicator.

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java
– Oyente que comienza a cargar datos cuando el usuario está a punto de llegar al final de ListView.

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java
– El EndlessListView. Puede usar esta clase directamente o ampliarla.

1646970072 520 Lista interminable de Android
tehcpu

Puede ser un poco tarde, pero la siguiente solución fue muy útil en mi caso. En cierto modo, todo lo que necesita hacer es agregar a su ListView un Footer y crear para ello addOnLayoutChangeListener.

http://developer.android.com/reference/android/widget/ListView.html#addFooterView(android.view.View)

Por ejemplo:

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");
    }
});

Este evento se activa una vez cuando un pie de página se vuelve visible y funciona a la perfección.

La clave de este problema es detectar el evento de carga adicional, iniciar una solicitud asíncrona de datos y luego actualizar la lista. También se necesita un adaptador con indicador de carga y otros decoradores. De hecho, el problema es muy complicado en algunos casos de esquina. solo un OnScrollListener la implementación no es suficiente, porque a veces los elementos no llenan la pantalla.

He escrito un paquete personal que admite una lista interminable para RecyclerViewy también proporciona una implementación de cargador asíncrono AutoPagerFragment lo que hace que sea muy fácil obtener datos de una fuente de varias páginas. Puede cargar cualquier página que desee en un RecyclerView en un evento personalizado, no solo en la página siguiente.

Aquí está la direccción: https://github.com/SphiaTower/AutoPagerRecyclerManager

  • El enlace está roto.

    – DSlomer64

    3 sep 2017 a las 23:02

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad