我想确定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方法后,如果尝试使用上述功能,则findFirstVisibleItemPositionfindLastVisibleItemPosition返回的项目位置是错误的。

我注意到他们俩都在后台使用getlayoutposition,而且我还注意到文档中的内容:


如果LayoutManager需要调用需要该项目的适配器位置的外部方法,则可以使用getAdapterPosition()或convertPreLayoutPositionToPostLayout(int)。


听起来convertPreLayoutPositionToPostLayout正是我想要的东西,但我不知道如何从RecyclerView中访问它。

有任何想法吗?

谢谢。

最佳答案

就我而言,一次在recyclerview中我最多只能有2个可见视图,并且
我在onScrolled中始终使用mostVisibleItemPosition
当用户滚动时播放视频内容。

因此getTop()返回此视图相对于其父视图的顶部位置,并且当用户开始滚动firstView离开屏幕时,firstView.getTop()将返回负值,而secondView.getTop()为正值且secondView到达顶部接近屏幕中心获取firstView.getTop()的绝对值,我们将确定父视图顶部上方firstView顶部有多少像素,获得secondView.getTop()我们将确定父底部上方secondView顶部有多少像素,是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;
                 ...
                }
            }
        }
    }

07-24 13:12