簡體   English   中英

在 RecyclerView 中查找完全可見的項目(如 TikTok 和 Instagram Story)

[英]Finding fully visible items in a RecyclerView (Like TikTok and Instagram Story)

所以我這里有一個自定義的recyclerview,用於實現像TikTok和Instagram故事這樣的全屏縱向視頻播放功能。 除了 RecyclerView 每次都找不到當前可見的項目之外,一切都運行良好。 當 recyclerview 滾動得太快,或者如果使用 swiperefreshlayout 多次刷新數據而沒有暫停時,viewholder 標簽的 position 在前一種情況下會變得不正確,在后一種情況下會變為 -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);
    }
}

這應該為您提供確切的完全可見的位置

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM