android - RecyclerView 适配器数据变化后如何确定最可见的 View 位置?

标签 android android-recyclerview recyclerview-layout

我想确定我的 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在幕后,我还注意到它在文档中说:

If LayoutManager needs to call an external method that requires the adapter position of the item, it can use getAdapterPosition() or convertPreLayoutPositionToPostLayout(int).

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

有什么想法吗?

谢谢。

最佳答案

在我的例子中,我在 recyclerview 中一次最多只能有 2 个可见 View ,并且 我在 onScrolled 中使用此方法,以便始终拥有 mostVisibleItemPosition 用于在用户滚动时播放视频内容。

因此 getTop() 返回此 View 相对于其父 View 的顶部位置,当用户开始滚动时 firstView 正在离开屏幕和 firstView。 getTop() 将返回负值,而 secondView.getTop() 为正,当 secondView top 几乎到达屏幕中心时,获取 的绝对值>firstView.getTop() 我们将确定 firstView top 从父 View 顶部上方有多少像素,而 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;
                 ...
                }
            }
        }
    }

关于android - RecyclerView 适配器数据变化后如何确定最可见的 View 位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50592034/

相关文章:

android - 从 native 代码访问 apk 中的压缩文件(从 zip 中读取 zip)

java - 如何将 Json 数组存储到 Java ArrayList 中?

android - 在 Android 浏览器中使用 input type=file capture=camera 上传照片时,防止照片自动保存到图库

android - RecyclerView 一次滚动一个元素

android - 我对项目中每个项目的适配器定位有疑问

android - 在 recyclerview 中更改下一个按钮的焦点顺序

android - 对内部存储中文件名的限制?

android - 如何从我的 fragment 上的 recyclerView 中的 View 以编程方式更改 View 的属性?

android - 如何在 RecyclerView 上获得点击(不是 child )

android - 在 RecyclerView 中垂直居中选定的项目