java - 在 RecyclerView 中查找完全可见的项目(如 TikTok 和 Instagram Story)

标签 java android android-recyclerview

所以我这里有一个自定义的 recyclerview 创建来实现全屏肖像视频播放功能,如 TikTok 和 Instagram 故事。除了 RecyclerView 每次都找不到当前可见的项目外,一切都运行良好。当 recyclerview 滚动得太快,或者使用 swiperefreshlayout 多次刷新 if 数据时,viewholder 标签的位置在前一种情况下变得不正确,在后一种情况下变为 -1,即使第一个项目完全可见。这是最不可或缺的部分,因为这是 recyclerview 决定播放哪个视频的地方,就像在 TikTok 或 Instagram Story 中一样。 playVideo 方法是所有可见项计算发生的地方。什么地方出了错?有更好的解决方案吗?希望你能回答。问候。

public class TiktokRecyclerview extends RecyclerView {

    int playPosition = - 1;
    boolean scrollingUp = false;
    int targetPosition;
    int currentPosition;
    Context context;
    TiktokViewHolder holder;

    public TiktokRecyclerview (@NonNull Context context) {
        super(context);
        init(context);
    }
    public TiktokRecyclerview (@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(final Context context) {
        this.context = context;
        addOnScrollListener(new OnScrollListener () {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                scrollingUp = dy > 0;
            }
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    playVideo(context);
                }
            }
        });
    }

    private void playVideo(Context context) {
        if (!scrollingUp) {
            targetPosition =
                ((androidx.recyclerview.widget.LinearLayoutManager) Objects . requireNonNull (getLayoutManager())).findLastVisibleItemPosition();
        } else {
            targetPosition =
                ((androidx.recyclerview.widget.LinearLayoutManager) Objects . requireNonNull (getLayoutManager())).findFirstVisibleItemPosition();
        }


        if (targetPosition != playPosition) { // Checks whether source and destination scroll item are same

            playPosition = targetPosition;

            if (!scrollingUp) {
                currentPosition =
                    ((androidx.recyclerview.widget.LinearLayoutManager) Objects . requireNonNull (getLayoutManager())).findLastCompletelyVisibleItemPosition();
            } else {
                currentPosition =
                    ((androidx.recyclerview.widget.LinearLayoutManager) Objects . requireNonNull (getLayoutManager())).findFirstCompletelyVisibleItemPosition();
            }

            View child = getChildAt (currentPosition);
            if (child == null) {
                return;
            }
            if (child.getTag() == null) {
                return;
            }
            holder = (TiktokViewHolder) child . getTag ();
            Log.d(TAG, "" + holder);
        }
    }
}

最佳答案

不确定为什么在 RecyclerView 中使用 vh 标签,因为现在他们有 ViewHolders

但是,您可以删除所有以 View child = getChildAt(currentPosition); 开头的代码,并仅替换为: holder = (RVAdapter.TiktokViewHolder) findViewHolderForLayoutPosition(currentPosition);

所以你的代码是:

  ...
  ...
  if (targetPosition != playPosition) { // Checks whether source and destination scroll item are same

        playPosition = targetPosition;

        if (!scrollingUp) {
            currentPosition =
                ((androidx.recyclerview.widget.LinearLayoutManager) Objects . requireNonNull (getLayoutManager())).findLastCompletelyVisibleItemPosition();
        } else {
            currentPosition =
                ((androidx.recyclerview.widget.LinearLayoutManager) Objects . requireNonNull (getLayoutManager())).findFirstCompletelyVisibleItemPosition();
        }

       //You may need to check if currentPosition is valid
        if (currentPosition < 0 || currentPosition >= getChildCount()) return;

        holder = (RVAdapter.TiktokViewHolder) findViewHolderForLayoutPosition(currentPosition);
        Log.d(TAG, "" + holder);
    }
}

这应该让你得到完全可见的位置

关于java - 在 RecyclerView 中查找完全可见的项目(如 TikTok 和 Instagram Story),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67636564/

相关文章:

java - 使用jsoup从两个标签之间提取不明的html内容?正则表达式?

Java正则表达式从一个句子中删除多次出现的模式

java - 将android连接到远程sql server

android - 使用recyclerview android过滤男性和女性结果searchview

android - 在数据加载到 Recycler View 之前加载 View

java - 如何在 Java 中将 "hash"长字符串转换为 String[64]

java - 有没有办法在设备内存 (RAM) 上最多存储 ~1GB?

android - 在 Android Studio 中安装后无法使用 Android Drawer Importer 插件

android - 通过代码更改 Recycler View 项目背景颜色

java - 在 Android 上使用 Dagger2 在某些设备上遇到 VerifyError