¿Cómo implementar una lista interminable con RecyclerView?

Resuelto erdna asked hace 54 años • 36 respuestas

Me gustaría cambiar ListViewa RecyclerView. Quiero usar el onScrollin OnScrollListenerpara RecyclerViewdeterminar si un usuario se desplazó hasta el final de la lista.

¿Cómo sé si un usuario se desplaza hasta el final de la lista para poder obtener nuevos datos de un servicio REST?

erdna avatar Jan 01 '70 08:01 erdna
Aceptado

Gracias a @Kushal y así lo implementé

private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        if (dy > 0) { //check for scroll down
            visibleItemCount = mLayoutManager.getChildCount();
            totalItemCount = mLayoutManager.getItemCount();
            pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();

            if (loading) {
                if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
                    loading = false;
                    Log.v("...", "Last Item Wow !");
                    // Do pagination.. i.e. fetch new data

                    loading = true;
                }
            }
        }
    }
});

No olvides agregar

LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
Abdulaziz Noor avatar Oct 30 '2014 00:10 Abdulaziz Noor

Haz estas variables.

private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 5;
int firstVisibleItem, visibleItemCount, totalItemCount;

Configure Desplazarse para ver la vista del reciclador.

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        visibleItemCount = mRecyclerView.getChildCount();
        totalItemCount = mLayoutManager.getItemCount();
        firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();

        if (loading) {
            if (totalItemCount > previousTotal) {
                loading = false;
                previousTotal = totalItemCount;
            }
        }
        if (!loading && (totalItemCount - visibleItemCount) 
            <= (firstVisibleItem + visibleThreshold)) {
            // End has been reached

            Log.i("Yaeye!", "end called");

            // Do something

            loading = true;
        }
    }
});

Nota: asegúrese de utilizar LinearLayoutManagercomo administrador de diseño para RecyclerView.

LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);

y para una grilla

GridLayoutManager mLayoutManager;
mLayoutManager = new GridLayoutManager(getActivity(), spanCount);
mRecyclerView.setLayoutManager(mLayoutManager);

¡Diviértete con tus pergaminos interminables! ^.^

Actualización: mRecyclerView. setOnScrollListener() está en desuso, simplemente reemplácelo con mRecyclerView.addOnScrollListener()y la advertencia desaparecerá. Puede leer más en esta pregunta SO .

Dado que Android ahora es compatible oficialmente con Kotlin, aquí hay una actualización para el mismo:

Hacer OnScrollListener

class OnScrollListener(val layoutManager: LinearLayoutManager, val adapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder>, val dataList: MutableList<Int>) : RecyclerView.OnScrollListener() {
    var previousTotal = 0
    var loading = true
    val visibleThreshold = 10
    var firstVisibleItem = 0
    var visibleItemCount = 0
    var totalItemCount = 0

    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        super.onScrolled(recyclerView, dx, dy)

        visibleItemCount = recyclerView.childCount
        totalItemCount = layoutManager.itemCount
        firstVisibleItem = layoutManager.findFirstVisibleItemPosition()

        if (loading) {
            if (totalItemCount > previousTotal) {
                loading = false
                previousTotal = totalItemCount
            }
        }

        if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
            val initialSize = dataList.size
            updateDataList(dataList)
            val updatedSize = dataList.size
            recyclerView.post { adapter.notifyItemRangeInserted(initialSize, updatedSize) }
            loading = true
        }
    }
}

y agréguelo a su RecyclerView así

recyclerView.addOnScrollListener(OnScrollListener(layoutManager, adapter, dataList))

Para ver un ejemplo de código completo, no dudes en consultar este repositorio de Github .

Kushal Sharma avatar Oct 25 '2014 11:10 Kushal Sharma