Получение видимых элементов в RecyclerView

Мне нужно знать, какие элементы отображаются в моем RecyclerView. В ListViews нет эквивалента метода OnScrollListener.onScroll(...). Я пытался работать с View.getGlobalVisibleRect(...), но этот хак слишком уродлив и не всегда работает.

Кто-нибудь какие-нибудь идеи?

Ответ 1

Первый/последний видимый дочерний элемент зависит от LayoutManager. Если вы используете LinearLayoutManager или GridLayoutManager, вы можете использовать

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

Например:

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

Для LinearLayoutManager первое/последнее зависит от упорядочения адаптера. Не запрашивать детей из RecyclerView; LayoutManager может предпочесть компоновку большего количества элементов, чем видно для кеширования.

Ответ 2

Наконец, я нашел решение узнать, является ли текущий элемент видимым, из события onBindViewHolder в адаптере.

Ключевым является метод isViewPartiallyVisible из LayoutManager.

В вашем адаптере вы можете получить LayoutManager из RecyclerView, который вы получаете как параметр из события onAttachedToRecyclerView.

Ответ 3

Вы можете использовать recyclerView.getChildAt() для получения каждого видимого дочернего элемента, а установка тега convertview.setTag(index) в этом представлении в коде адаптера поможет вам связать его с данными адаптера.

Ответ 4

Для StaggeredGridLayoutManager сделайте следующее:

RecyclerView rv = findViewById(...);
StaggeredGridLayoutManager lm = new StaggeredGridLayoutManager(...);
rv.setLayoutManager(lm);

И для получения видимых видов элементов:

int[] viewsIds = lm.findFirstCompletelyVisibleItemPositions(null);
ViewHolder firstViewHolder = rvPlantios.findViewHolderForLayoutPosition(viewsIds[0]);
View itemView = viewHolder.itemView;

Не забудьте проверить, пуст ли он.

Ответ 5

Следующие методы Linear/Grid LayoutManager можно использовать для проверки того, какие элементы visible

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

и если вы хотите отследить, is item visible on screen для некоторого порога, вы можете обратиться к следующему блогу.

https://proandroiddev.com/detecting-list-items-perceived-by-user-8f164dfb1d05

Ответ 6

Приложение:

Предложенные функции findLast... Position() не работают правильно в сценарии с сворачивающейся панелью инструментов, когда панель инструментов развернута.

Кажется, что вид рециркулятора имеет фиксированную высоту, и, хотя панель инструментов развернута, рециркулятор перемещается вниз, частично за пределы экрана. Как следствие, результаты предложенных функций слишком высоки. Пример: последний видимый элемент называется # 9, но на самом деле элемент # 7 является последним на экране.

Это поведение также является причиной, по которой моему представлению часто не удавалось прокрутить до правильной позиции, то есть scrollToPosition() не работал правильно (я окончательно свернул панель инструментов программно).

Ответ 7

Попробуй это:

int currentVisibleItem = getCurrentVisibleItem();

public static int getCurrentVisibleItem() {

    LinearLayoutManager layoutManager = ((LinearLayoutManager)mRecyclerView.getLayoutManager());

    return layoutManager.findFirstVisibleItemPosition();

}