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.