[英]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.