所以我这里有一个自定义的 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/