I try to open each video when I click on them but what I get instead is only the second video (sometimes first video). For example, when I click on "16 best video ideas for small business" I want it to open that particular video. But what I get instead is "this tiny camera can show the world from a bug's point of view. I think the problem occurs because of for loop inside query in UserHomeVideoAdapter.
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);
}
}
}
I logged videoId inside that is assigned inside for loop. Sometimes it returns ids in this order "1"; "2" and sometimes it returns like this "2"; "1". When it returns in this order "1"; "2" click opens second video even if I click first video and when it returns like this "2"; "1" click opens first video even if I click second video.
If you need additional code to solve the problem please ask and I will provide it as soon as possible. Any help is appreciated. Thanks
The short answer is that onBindViewHolder()
is trying to do too much. From the documentation :
Called by RecyclerView to display the data at the specified position. This method should update the contents of the ViewHolder#itemView to reflect the item at the given position.
In other words, onBindViewHolder()
is only responsible for one single item in the RecyclerView
. However, you are trying to fetch all of the data for every element in the list. Instead, you should fetch the data external to your adapter and pass it in as a parameter. Then onBindViewHolder()
should update the UI elements of a view inside the RecyclerView to display whatever you want for one single item.
Google has a great example CustomerAdapter
. First, the constructor takes the list of data that will be displayed:
public CustomAdapter(String[] dataSet) {
mDataSet = dataSet;
}
Then onbindViewHolder()
is only responsible for setting what is displayed in the UI of a single item in the RecyclerView:
@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]);
}
It does NOT try to get data or loop over a list or anything else. All of that is someone else's responsibility.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.