为啥 recyclerview 返回错误的项目?
Posted
技术标签:
【中文标题】为啥 recyclerview 返回错误的项目?【英文标题】:Why recyclerview returns wrong item?为什么 recyclerview 返回错误的项目? 【发布时间】:2021-09-04 01:23:32 【问题描述】:我尝试在单击 itemview 时打开视频。有时它可以正常工作,但有时当我单击第一个视频时它会打开第二个视频,反之亦然。我试图实现的是当我点击第一个 recyclerview 项目时打开第一个视频等等。
UserHomeVideoAdapter.java:
public class UserHomeVideoAdapter extends FirestoreRecyclerAdapter<FollowList, UserHomeVideoAdapter.UserVideoHolder>
Context context;
final FirebaseFirestore db = FirebaseFirestore.getInstance();
String thumbUrl, videoTitle, videoUrl, videoDesc, videoId, publisherId;
ArrayList<String> videoIdArrayList = new ArrayList<>();
public UserHomeVideoAdapter(@NonNull @NotNull FirestoreRecyclerOptions<FollowList> options, Context context)
super(options);
this.context = context;
@Override
protected void onBindViewHolder(@NonNull @NotNull UserVideoHolder holder, int position, @NonNull @NotNull FollowList model)
Query query = db.collection("Videos").whereEqualTo("publisherId", model.getUserId());
query.get().addOnCompleteListener(task ->
if (task.isSuccessful())
if (task.getResult() != null)
for (QueryDocumentSnapshot documentSnapshot : task.getResult())
Video video = documentSnapshot.toObject(Video.class);
thumbUrl = video.getThumbUrl();
videoTitle = video.getVideoTitle();
videoUrl = video.getVideoUrl();
videoDesc = video.getVideoDesc();
videoId = video.getVideoId();
publisherId = video.getPublisherId();
videoIdArrayList.add(videoId);
if (task.getResult().size() > 0)
db.collection("Users").document(model.getUserId()).get().addOnSuccessListener(documentSnapshot ->
if (documentSnapshot != null)
final User user = documentSnapshot.toObject(User.class);
if (user != null)
if (user.getUserImageUrl() == null)
holder.userProfileImage.setImageResource(R.drawable.ic_launcher_background);
else
Glide.with(context).load(Uri.parse(user.getUserImageUrl())).into(holder.userProfileImage);
).addOnFailureListener(e -> Toast.makeText(context, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show());
Glide.with(context).load(thumbUrl).into(holder.videoImageView);
holder.videoTitle.setText(videoTitle);
holder.mainContainerVideo.setVisibility(View.VISIBLE);
else if (task.getResult().size() == 0)
holder.mainContainerVideo.getLayoutParams().height = 0;
holder.mainContainerVideo.getLayoutParams().width = 0;
else
Toast.makeText(context, String.valueOf(task.getException()), Toast.LENGTH_SHORT).show();
).addOnFailureListener(e -> Toast.makeText(context, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show());
holder.itemView.setOnClickListener(view ->
Intent intent = new Intent(context, VideoActivity.class);
intent.putExtra("videoPublisherUserName", model.getUserName());
intent.putExtra("thumbUrl", thumbUrl);
intent.putExtra("videoPublisherEmail", model.getUserEmail());
intent.putExtra("videoUrl", videoUrl);
intent.putExtra("videoId", videoIdArrayList.get(position));
intent.putExtra("videoPublisherFullName", model.getUserFullName());
intent.putExtra("videoPublisherId", publisherId);
context.startActivity(intent);
Log.d("Bax", videoIdArrayList.get(position));
);
@NonNull
@NotNull
@Override
public UserVideoHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType)
View v = LayoutInflater.from(context).inflate(R.layout.video_cell, parent, false);
return new UserVideoHolder(v);
public static class UserVideoHolder extends RecyclerView.ViewHolder
RelativeLayout mainContainerVideo;
CircleImageView userProfileImage;
TextView videoTitle;
ImageView videoImageView;
public UserVideoHolder(@NonNull @NotNull View itemView)
super(itemView);
mainContainerVideo = itemView.findViewById(R.id.mainContainerVideo);
userProfileImage = itemView.findViewById(R.id.userProfileImage);
videoTitle = itemView.findViewById(R.id.videoTitle);
videoImageView = itemView.findViewById(R.id.videoImageView);
我不明白我的代码存在的问题,因此感谢您提供任何帮助。谢谢
【问题讨论】:
您的 recyclerview 目前有多少个视频? @skafle 现在是 2,但它可以随着用户将来上传而改变 【参考方案1】:这里的问题是您的videoIdArrayList.add(videoId)
没有被重置。每次您的 recyclerview 加载时,它都会查询数据库并在 videoIdArrayList
中添加 videoId
并不断添加。
这会弄乱要发送到下一个活动的 videoId。
因此,请清除您的 videoIdArrayList
每次 recyclerview 加载并在此之后添加 Id。
因此,在 firebase 查询中的 for 循环之前,只需清除列表即可。
videoIdArrayList.clear()
应该可以完美运行。
【讨论】:
不幸的是,我按照您的建议做了,但没有得到任何结果。我什至尝试在我的 clicklistener 中清除 arraylist,但又没有结果。 是的...正如@anatoli 建议的那样,您的查询被执行的次数与您的recyclerview 在给定时间持有的项目数一样多。因此,最好将您的查询代码传输到不同的文件,然后在初始化适配器时将列表传递给适配器。【参考方案2】:onBindViewHolder
对RecyclerView
中的每个项目执行。一次都没有
Query query = db.collection("Videos").whereEqualTo("publisherId", model.getUserId());
返回 List
,而不是项目。
videoIdArrayList.add(videoId);
可以多次执行第一项。
String thumbUrl, videoTitle, videoUrl, videoDesc, videoId, publisherId;
在 Query 中设置为 onBindViewHolder
。再次为RecyclerView
中的每个项目执行onBindViewHolder
。一次都没有。
你必须重构你的适配器。
-
通过您的适配器执行查询。
目前尚不清楚,哪些物品会收到持有人。 (对我来说。如果你很清楚 -> 跳过这一步)
而不是
holder.videoTitle
在 holder 中创建一个方法(例如 void configView(YourItem item)
),并在 holder 中执行与该项目有关的一切。
【讨论】:
以上是关于为啥 recyclerview 返回错误的项目?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 RecyclerView 项目在 GridLayoutManager 中随机移动位置?
为啥 RecyclerView 项目在点击两次后才改变背景颜色?
为啥 notifyItemChanged(position) 不更新 RecyclerView 中的所有项目?
为啥这些随机标记出现在每个 recyclerview 和 viewpager 项目中?