Obtener elementos visibles en RecyclerView

Resuelto rekire asked hace 54 años • 12 respuestas

Necesito saber qué elementos se muestran actualmente en mi RecyclerView. No existe un equivalente al OnScrollListener.onScroll(...)método en ListViews. Intenté trabajar conView.getGlobalVisibleRect(...) , pero ese truco es demasiado feo y no siempre funciona.

¿Alguien tiene alguna idea?

rekire avatar Jan 01 '70 08:01 rekire
Aceptado

El primer/último hijo visible depende del LayoutManager. Si estás usando LinearLayoutManagero GridLayoutManager, puedes usar

int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();

Por ejemplo:

GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();

Para LinearLayoutManager, primero/último depende del pedido del adaptador. No consulte a los niños de RecyclerView; LayoutManagerEs posible que prefiera diseñar más elementos de los visibles para el almacenamiento en caché.

yigit avatar Jul 31 '2014 07:07 yigit

Para aquellos que tienen una lógica para implementar dentro del adaptador RecyclerView, aún pueden usar el enfoque @ernesto combinado con un scrollListener para obtener what you wantcómo se consulta RecyclerView. Dentro del adaptador tendrás algo como esto:

@Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if(manager instanceof LinearLayoutManager && getItemCount() > 0) {
            LinearLayoutManager llm = (LinearLayoutManager) manager;
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                }

                @Override
                public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                        int visiblePosition = llm.findFirstCompletelyVisibleItemPosition();
                        if(visiblePosition > -1) {
                            View v = llm.findViewByPosition(visiblePosition);
                            //do something
                            v.setBackgroundColor(Color.parseColor("#777777"));
                        }
                }
            });
        }
    }
Aleyam avatar Jun 02 '2019 18:06 Aleyam

Finalmente, encontré una solución para saber si el elemento actual es visible, desde el evento onBindViewHolder en el adaptador.

La clave es el método isViewPartiallyVisible de LayoutManager.

En su adaptador, puede obtener LayoutManager de RecyclerView, que obtiene como parámetro del evento onAttachedToRecyclerView .

Ernesto Vega avatar Feb 06 '2018 15:02 Ernesto Vega

Todas las respuestas anteriores son correctas y me gustaría agregar también una instantánea de mis códigos de trabajo.

recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
           // Some code when initially scrollState changes
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            // Some code while the list is scrolling
            LinearLayoutManager lManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            int firstElementPosition = lManager.findFirstVisibleItemPosition();
            
        }
    });
Ishimwe Aubain Consolateur avatar Sep 24 '2020 21:09 Ishimwe Aubain Consolateur

Puede usarlo recyclerView.getChildAt()para obtener cada hijo visible y configurar alguna etiqueta convertview.setTag(index)en estas vistas en el código del adaptador lo ayudará a relacionarlo con los datos del adaptador.

Sreejith B Naick avatar Jul 28 '2014 06:07 Sreejith B Naick