为什么 firebase recyclerview 无法正常工作?

问题描述

enter image description here

当我点击每个视频时,我尝试打开它们,但我得到的只是第二个视频(有时是第一个视频)。例如,当我点击“适合小型企业的 16 个最佳视频创意”时,我希望它打开那个特定的视频。但我得到的是“这个微型相机可以从错误的角度展示世界。我认为问题的出现是因为 UserHomeVideoAdapter 中的 for 循环内部查询

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() 尝试做的太多了。来自the documentation

由 RecyclerView 调用以显示指定位置的数据。此方法应更新 ViewHolder#itemView 的内容以反映给定位置的项目。

换句话说,onBindViewHolder() 只负责RecyclerView中的一项。但是,您正在尝试获取列表中每个元素的所有数据。相反,您应该获取适配器外部的数据并将其作为参数传递。然后 onBindViewHolder() 应该更新 RecyclerView 内视图的 UI 元素,以显示您想要的单个项目的任何内容。

Google has a great example 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]);
    }

它不会尝试获取数据或遍历列表或其他任何内容。所有这些都是别人的责任。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...