RamammDev
RamammDev

Reputation: 133

Why recyclerview returns wrong item?

I try to open video as I click on itemview. Sometimes it works correctly but sometimes it opens the second video when I click first video and vice versa. What I try to achieve is to open first video when I click first recyclerview item and so on.

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);
        }
    }
}

I don't understand the problem with my code so any help is appreciated. Thanks

Upvotes: 0

Views: 56

Answers (2)

skafle
skafle

Reputation: 1025

The problem here is your videoIdArrayList.add(videoId) is not being reset. Every time your recyclerview loads, it queries the database and adds videoId in the videoIdArrayList and that keeps adding.

That is messing up the videoId being sent to the next activity. So, clear your videoIdArrayList Every time the recyclerview loads and add Id's after that.

So, before your for loop in firebase query, just clear the list. videoIdArrayList.clear()

Should work perfectly.

Upvotes: 1

marina
marina

Reputation: 1680

onBindViewHolder executes for each item in RecyclerView. Not once

Query query = db.collection("Videos").whereEqualTo("publisherId", model.getUserId()); returns a List, not item.

videoIdArrayList.add(videoId); could be executed for first item many times.

String thumbUrl, videoTitle, videoUrl, videoDesc, videoId, publisherId; are setted in onBindViewHolder in Query. Again onBindViewHolder executes for each item in RecyclerView. Not once.

You must refactor your adapter.

  1. execute query over your adapter.
  2. It is not clear, what items receive holders. (for me. if for you it is clear -> skip the step)
  3. instead holder.videoTitle make a method in holder (for example void configView(YourItem item)) and evertyhing regarding to that item execute in holder.

Upvotes: 0

Related Questions