Как определить наиболее видимую позицию вида после изменения данных адаптера RecyclerView? - PullRequest
0 голосов
/ 29 мая 2018

Я хочу определить наиболее видимый элемент в RecyclerView, поэтому я использую следующий метод:

public int getMostVisibleIndex() {
        // try to figure which child is the most visible on screen

        LinearLayoutManager layoutManager = ((LinearLayoutManager) getLayoutManager());

        mFirstVisibleIndex = layoutManager.findFirstVisibleItemPosition();
        mLastVisibleIndex = layoutManager.findLastVisibleItemPosition();

        // How do I use convertPreLayoutPositionToPostLayout() ?

        VisibleIndex mostVisible = null;
        if (mFirstVisibleIndex != -1|| mLastVisibleIndex != -1) {


            // if it's not the same
            if (mFirstVisibleIndex != mLastVisibleIndex) {
                LinearLayoutManager linearLayoutManager = (LinearLayoutManager) this.getLayoutManager();

                // get the visible rect of the first item
                Rect firstPercentageRect = new Rect();
                linearLayoutManager.findViewByPosition(mFirstVisibleIndex).getGlobalVisibleRect(firstPercentageRect);

                // get the visible rect of the last item
                Rect lastPercentageRect = new Rect();
                linearLayoutManager.findViewByPosition(mLastVisibleIndex).getGlobalVisibleRect(lastPercentageRect);

                // since we're on a horizontal list
                if (firstPercentageRect.width() > lastPercentageRect.width()) {
                    return mFirstVisibleIndex;
                } else {
                    return mLastVisibleIndex;
                }

            } else {
                return mFirstVisibleIndex;
            }
        }
        return -1;
    }

Он отлично работает, но после изменения набора данных и вызова любых методов notify*Changedв моем адаптере, если я пытаюсь использовать вышеупомянутую функцию, позиции элементов, которые возвращают findFirstVisibleItemPosition и findLastVisibleItemPosition, неверны.

Я заметил, что они оба используют getlayoutposition за кадроми я также заметил, что в документации написано:

Если LayoutManager требуется вызвать внешний метод, для которого требуется позиция адаптера элемента, он может использовать getAdapterPosition () или convertPreLayoutPositionToPostLayout (int).

Звучит так, как будто convertPreLayoutPositionToPostLayout именно то, что я ищу, но я не знаю, как получить к нему доступ изнутри RecyclerView.

Есть идеи?

Спасибо.

1 Ответ

0 голосов
/ 03 октября 2018

В моем случае у меня может быть только максимум 2 видимых вида одновременно в обзоре переработчика, и я использую этот метод в onScrolled, чтобы всегда иметь mostVisibleItemPosition для воспроизведения видеоконтента при прокрутке пользователя.

Таким образом, getTop() возвращает верхнюю позицию этого представления относительно его родителя, и когда пользователь начинает прокручивать, firstView выходит из экрана, а firstView.getTop() возвращает минус, в то время как secondView.getTop() является положительным, и когда secondView достигает вершины.почти в центре экрана, получая абсолютное значение firstView.getTop(), мы определим, сколько пикселей firstView top находится сверху от родительского представления сверху, и, получив secondView.getTop(), мы определим, сколько пикселей secondView top находится выше родительского основания, и этогде mostVisibleItemPosition будет изменено.

  private void detectMostVisibleItem() {
        int firstItemPosition = layoutManager.findFirstVisibleItemPosition();
        int secondItemPosition = layoutManager.findLastVisibleItemPosition();
        if (firstItemPosition == secondItemPosition) {
            mostVisibleItemPosition = firstItemPosition;
        } else {
            View firstView = layoutManager.findViewByPosition(firstItemPosition);
            View secondView = layoutManager.findViewByPosition(secondItemPosition);
            if (Math.abs(firstView.getTop()) <= Math.abs(secondView.getTop())) {
                if (mostVisibleItemPosition != firstItemPosition) {
                    mostVisibleItemPosition = firstItemPosition;
                 ...
                }
            } else {
                if (mostVisibleItemPosition != secondItemPosition) {
                    mostVisibleItemPosition = secondItemPosition;
                 ...
                }
            }
        }
    }
...