java - 为什么 firebase recyclerview 无法正常工作?
问题描述
当我点击它们时,我尝试打开每个视频,但我得到的只是第二个视频(有时是第一个视频)。例如,当我点击“适合小型企业的 16 个最佳视频创意”时,我希望它打开那个特定的视频。但我得到的是“这个微型相机可以从错误的角度展示世界。我认为问题的出现是因为 UserHomeVideoAdapter 中的 for loop inside 查询。
UserHomeVideoAdapter.java:
public class UserHomeVideoAdapter extends FirestoreRecyclerAdapter<FollowList, UserHomeVideoAdapter.UserVideoHolder> {
Context context;
final FirebaseFirestore db = FirebaseFirestore.getInstance();
String thumbUrl, videoTitle, videoUrl, videoDesc, videoId, publisherId;
Video video;
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 = documentSnapshot.toObject(Video.class);
Log.d("Data", documentSnapshot.getId() + " => " + documentSnapshot.getData());
thumbUrl = video.getThumbUrl();
videoTitle = video.getVideoTitle();
videoUrl = video.getVideoUrl();
videoDesc = video.getVideoDesc();
videoId = video.getVideoId();
publisherId = video.getPublisherId();
}
if (task.getResult().size() != 0) {
Glide.with(context).load(model.getUserImageUrl()).into(holder.userProfileImage);
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.videoContainer.setOnClickListener(v -> {
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", videoId);
intent.putExtra("videoPublisherFullName", model.getUserFullName());
intent.putExtra("videoPublisherId", publisherId);
context.startActivity(intent);
});
}
@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 videoContainer, mainContainerVideo;
CircleImageView userProfileImage;
TextView videoTitle;
ImageView videoImageView;
public UserVideoHolder(@NonNull @NotNull View itemView) {
super(itemView);
mainContainerVideo = itemView.findViewById(R.id.mainContainerVideo);
videoContainer = itemView.findViewById(R.id.videoContainer);
userProfileImage = itemView.findViewById(R.id.userProfileImage);
videoTitle = itemView.findViewById(R.id.videoTitle);
videoImageView = itemView.findViewById(R.id.videoImageView);
}
}
}
我在 for 循环中分配了 videoId 。有时它会按“1”的顺序返回 id;“2”,有时它会像这样“2”返回;“1”。当它按此顺序返回“1”时;即使我单击第一个视频并且当它像这样“2”返回时,“2”单击也会打开第二个视频;即使我单击第二个视频,“1”单击也会打开第一个视频。
如果您需要其他代码来解决问题,请询问,我会尽快提供。任何帮助表示赞赏。谢谢
解决方案
简短的回答是onBindViewHolder()
试图做太多事情。从文档中:
由 RecyclerView 调用,在指定位置显示数据。此方法应更新 ViewHolder#itemView 的内容以反映给定位置的项目。
换句话说,onBindViewHolder()
只负责RecyclerView
. 但是,您正在尝试获取列表中每个元素的所有数据。相反,您应该获取适配器外部的数据并将其作为参数传递。然后onBindViewHolder()
应该更新 RecyclerView 内视图的 UI 元素,以显示您想要的单个项目的任何内容。
谷歌有一个很好的例子CustomerAdapter
。首先,构造函数获取将要显示的数据列表:
public CustomAdapter(String[] dataSet) {
mDataSet = dataSet;
}
然后onbindViewHolder()
只负责设置 RecyclerView 中单个 item 的 UI 中显示的内容:
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
Log.d(TAG, "Element " + position + " set.");
// Get element from your dataset at this position and replace the contents of the view
// with that element
viewHolder.getTextView().setText(mDataSet[position]);
}
它不会尝试获取数据或遍历列表或其他任何内容。所有这些都是别人的责任。
推荐阅读
- reactjs - 使用 Yarn 2 链接 React 组件时未找到模块错误
- python - 有没有办法比较 Python 中的列表,类似于 excel 中的 vlookup
- reactjs - react/antd中的抽屉在右侧没有打开,就在所有组件的下方
- php - 更新(刷新)PHP 变量而不刷新网站
- c# - CA2235:字段是可序列化类型的成员,但属于不可序列化的 .NET 标准类型
- python - 如何将纯文本列表转换为 python 3 列表
- awk - 检查 GAWK 二进制字符
- .net - 是否可以从 .Net Framework 项目制作全局工具?
- c++ - C++ Hello World 程序中的错误
- android - 线性布局中的浮动操作按钮未显示