0

I have a RecylcerView holding cards with messages, each has a like and a dislike button. When the like button is clicked the user-ID is stored in my database and the user should not be able to like it again. If he clicks it again his action should reset his like. Same should hold true for dislikes.

In my Adapter in onBindViewHolder I check in my database if the user has already clicked the button. If so, I replace the white up-arrow image with a red arrow. I also set a tag to the ImageView by setTag. Where 0 represents the unvoted case and 1 if the like-button was pressed before :

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    final String mUID = getUserID();
    final String postID = getPostID(position);
    final PostViewHolder holder1 = (PostViewHolder) holder;

    //REFERENCE WHERE USER IDs ARE STORED WHEN THEY LIKE THE POST     
    mRefForUID = rootRef.child("likesUIDs").child(postID);

    ValueEventListener valueEventListenerForUID = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            //IF USER HAS LIKED A REFERENCE IS STORED WITH "mUID+"
            if (dataSnapshot.hasChild(mUID+"+")){
                //SET RED ARROW IF UP IS CLICKED BEFORE AND SETTAG TO 1
                holder1.mUp.setTag(1);
                holder1.mUp.setImageResource(R.drawable.arrow_up_red);

            } if(dataSnapshot.hasChild(mUID+"-")) {
              //SAME AS ABOVE FOR THE DISLIKED CASE
              //HERE I COULD SET THE TAG TO -1 

            } else {
                //IF USER ID IS NOT KNOWN HE HAS NOT CLICKED
                //SO I SET THE TAG TO 0 FOR THIS CASE
                holder1.mUp.setTag(0);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    };
    mRefForUID.addListenerForSingleValueEvent(valueEventListenerForUID);
}

In my ViewHolder I define the onClick events of the buttons (in my case these are ImageViews). If the button was clicked before the onClick event should be different, so I distinguish between these states with the help of my previously initialized tag and a switch case algorithm:

public class PostViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    public ImageView mUp;
    public ImageView mDown;

    public PostViewHolder(View itemView, postClickListener listener){
        super(itemView);

        mUp = mView.findViewById(R.id.arrowUp);
        mDown = mView.findViewById(R.id.arrowDown);

        mUp.setOnClickListener(this);
        mDown.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        if (v.getId() == mUp.getId()){
            int tag = (int) mUp.getTag();
            int position = getAdapterPosition();

            switch(tag){

                case 0:

                    //CASE 0 = NOT CLICKED BEFORE
                    //MAKE A NORMAL LIKE AND SET THE TAG TO 1 FROM HERE

                case 1:

                    //CASE 1 = UPVOTE IS CLICKED BEFORE
                    //UNLIKE AND SET THE TAG TO 0 HERE

            }

        }

    }

I leave out the case for the down-vote. So the assignment of the correct ImageView does work. When I open the app I get the red upvote button if it has been upvoted before. But the tag is always 0 when I start the app! So the onBindViewHolder does the following correctly holder1.mUp.setImageResource(R.drawable.arrow_up_red);, but does not set the tag holder1.mUp.setTag(1);.

It particularly does not work when opening the app for the first time. When clicking a couple of times I get the correct tags, since they will get set in the ViewHolder.

I hope to find the mistake or even a better solution for my intention.

Shruti
  • 803
  • 9
  • 26
P. Wulf
  • 18
  • 7
  • Hope you are using Firebase transactions for like-dislike functionality – Shruti Apr 04 '18 at 05:14
  • @Shruti, thanks for your comment. Yes I do! The like-dislike functionality seems to work fine. Only the tag (initialized in onBindViewHolder) is not set correctly when running the app. – P. Wulf Apr 04 '18 at 05:15
  • How about fetching data from Firebase in activity or fragment, store it in a list and passing that list to your adapter and then setting image tag in onBindViewHolder by checking list data item according to position? – Shruti Apr 04 '18 at 05:24
  • @Shruti, I use Firebase Firestore to store the posts and the Realtime Database to store likes. In my Activity I get all information such as posted message, timestamp, poster-ID and pass it to my Adapter as a list. To be honest, I do not know how to expand this list which is fetched from Firestore with an additional tag (stored in the RTDB) for each post depending on the userID. Btw, [this](https://stackoverflow.com/questions/49561360/using-data-from-firestore-and-firebase-rtdb-in-single-recyclerview) is the procedure I use. – P. Wulf Apr 04 '18 at 05:32

0 Answers0