Hafeez Lawal Olabisi
Hafeez Lawal Olabisi

Reputation: 45

Issue with RecyclerView Adapter

This image explain my question

enter image description here

I have a small issue with recycler view adapter, i have two button up vote and down vote, which toggles onclick, but when i click up vote for example it changes the color of the drawable on the image, but the on click affects other up vote button in other cards. This is the code am using for toggle.

boolean up, down, bookmark = false;

@Override
public void onBindViewHolder(final PostsViewHolder holder, int position) {

holder.upvote.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(!up){
                holder.upvote.setColorFilter(context.getResources().getColor(R.color.colorAccent));
                holder.downvote.setColorFilter(null);
                holder.downCount.setText("0");
                holder.upCount.setText("1");

                up = true;
                down = false;
            }
            else{
                holder.upvote.setColorFilter(null);
                holder.downCount.setText("0");
                holder.upCount.setText("0");
                up = false;
            }
        }
    });

this is the whole adapter class

public class NewsAdapter extends RealmBaseRecyclerViewAdapter<NewsTrend, NewsAdapter.PostsViewHolder> {

public RealmResults<NewsTrend> realmResults;
public Context context;
public EventListener eventListener;

 static boolean up, down, bookmark = false;

public NewsAdapter(Context context, RealmResults<NewsTrend> realmResults, boolean automaticUpdate) {
    super(context, realmResults, automaticUpdate);
    this.realmResults = realmResults;
    this.context = context;
}

public void setEventListener(EventListener eventListener) {
    this.eventListener = eventListener;
}

@Override
public PostsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_news_list_items, viewGroup, false);
    PostsViewHolder mediaViewHolder = new PostsViewHolder(v);
    return mediaViewHolder;
}

@Override
public void onBindViewHolder(final PostsViewHolder holder, int position) {

    final NewsTrend postsData = getItem(position);

    String eventName = postsData.getTitle();
    String eventDate = postsData.getTimestamp();




    Spanned decodedTitle = Html.fromHtml(eventName);

    if(postsData.getType().equals("bella")){
        holder.sourceImage.setImageResource(R.drawable.bella);
    }else if(postsData.getType().equals("punch")){
        holder.sourceImage.setImageResource(R.drawable.punch);
    }else if(postsData.getType().equals("linda")){
        holder.sourceImage.setImageResource(R.drawable.lib);
    }

    holder.eventName.setText(decodedTitle);
    holder.startEvent.setText(getSplitDate(eventDate));
    holder.eventDescription.setText(postsData.getHref());
    holder.sourceName.setText(postsData.getType());

        Glide.with(context)
                .load(postsData.getImage())
                .centerCrop()
                .placeholder(R.drawable.tw_logo)
                .into(holder.mDisplayGeneratedImage);

    /*Animation animation;
    animation = AnimationUtils.loadAnimation(context, R.anim.fade_in);
    holder.postContentHolder.startAnimation(animation);*/

    holder.postContentHolder.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            new FinestWebView.Builder(context)
                    .theme(R.style.FinestWebViewTheme)
                    .titleDefault("What's Trending")
                    .showUrl(false)
                    .statusBarColorRes(R.color.bluePrimaryDark)
                    .toolbarColorRes(R.color.colorPrimary)
                    .titleColorRes(R.color.finestWhite)
                    .urlColorRes(R.color.colorPrimaryDark)
                    .iconDefaultColorRes(R.color.finestWhite)
                    .progressBarColorRes(R.color.PrimaryDarkColor)
                    .stringResCopiedToClipboard(R.string.copied_to_clipboard)
                    .stringResCopiedToClipboard(R.string.copied_to_clipboard)
                    .stringResCopiedToClipboard(R.string.copied_to_clipboard)
                    .showSwipeRefreshLayout(true)
                    .swipeRefreshColorRes(R.color.bluePrimaryDark)
                    .menuSelector(R.drawable.selector_light_theme)
                    .menuTextGravity(Gravity.CENTER)
                    .menuTextPaddingRightRes(R.dimen.defaultMenuTextPaddingLeft)
                    .dividerHeight(0)
                    .gradientDivider(false)
                    .setCustomAnimations(R.anim.slide_up, R.anim.hold, R.anim.hold, R.anim.slide_down)
                    .show(postsData.getHref());
        }
    });



    holder.share.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
            sharingIntent.setType("text/plain");
            String shareBody = postsData.getHref();
            sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, postsData.getTitle());
            sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
            context.startActivity(Intent.createChooser(sharingIntent, "Share via"));
        }
    });


    holder.upvote.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(!up){
                holder.upvote.setColorFilter(context.getResources().getColor(R.color.colorAccent));
                holder.downvote.setColorFilter(null);
                holder.downCount.setText("0");
                holder.upCount.setText("1");

                up = true;
                down = false;
            }
            else{
                holder.upvote.setColorFilter(null);
                holder.downCount.setText("0");
                holder.upCount.setText("0");
                up = false;
            }
        }
    });

    holder.downvote.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(!down){
                holder.downvote.setColorFilter(context.getResources().getColor(R.color.colorAccent));
                holder.upvote.setColorFilter(null);
                holder.downCount.setText("1");
                holder.upCount.setText("0");
                up = false;
                down = true;
            }
            else{
                holder.downvote.setColorFilter(null);
                holder.downCount.setText("0");
                holder.upCount.setText("0");
                down = false;
            }
        }
    });


    holder.bookmark.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(!bookmark){
                holder.bookmark.setColorFilter(context.getResources().getColor(R.color.colorAccent));
                bookmark = true;
            }else{
                holder.bookmark.setColorFilter(null);
                bookmark = false;
            }
        }
    });



}

@Override
public NewsTrend getItem(int i) {
    return realmResults.get(i);
}

public void swapData(RealmResults<NewsTrend> realmResults) {
    this.realmResults = realmResults;
    notifyDataSetChanged();
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

@Override
public int getItemCount() {
    return realmResults.size();
}

public static class PostsViewHolder extends RecyclerView.ViewHolder {
    LinearLayout postContentHolder;

    public RobotoTextView startEvent;
    public RobotoTextView eventName;
    public RobotoTextView eventDescription;
    public RobotoTextView sourceName;

    public TextView upCount;
    public TextView downCount;

    public ImageButton share;
    public ImageButton upvote;
    public ImageButton downvote;
    public ImageButton bookmark;

    public ImageView sourceImage;
    public ImageView mDisplayGeneratedImage;

    PostsViewHolder(View itemView) {
        super(itemView);
        postContentHolder = (LinearLayout) itemView.findViewById(R.id.post_content_holder);
        startEvent = (RobotoTextView) itemView.findViewById(R.id.event_start);
        eventName = (RobotoTextView) itemView.findViewById(R.id.event_name);
        eventDescription = (RobotoTextView) itemView.findViewById(R.id.event_description);
        mDisplayGeneratedImage = (ImageView) itemView.findViewById(R.id.rlv_name_view);
        share = (ImageButton) itemView.findViewById(R.id.share);
        sourceName = (RobotoTextView) itemView.findViewById(R.id.sourceName);
        sourceImage = (ImageView) itemView.findViewById(R.id.sourceImg);
        upvote = (ImageButton) itemView.findViewById(R.id.upVote);
        downvote = (ImageButton) itemView.findViewById(R.id.downVote);
        upCount = (TextView) itemView.findViewById(R.id.upCount);
        downCount = (TextView) itemView.findViewById(R.id.downCount);
        bookmark = (ImageButton) itemView.findViewById(R.id.bookmark);
    }
}

public interface EventListener {
    void onItemClick(final View view, NewsTrend postsData);
}


public String getSplitDate(String dateString){

    String[] parts = dateString.split("T");
    String part1 = parts[0]; // 004

    return part1;
}

}

Upvotes: 1

Views: 434

Answers (2)

Divyang Panchal
Divyang Panchal

Reputation: 1909

Use setTag() to identify which item is clicked, Copy this code

boolean up, down, bookmark = false;

        @Override
        public void onBindViewHolder(final PostsViewHolder holder, int position) {

            holder.upvote.setTag(holder); // set tag to get clicked item view
            holder.upvote.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    PostsViewHolder viewHolder =(PostsViewHolder) v.getTag();
                    if(!v.isChecked()){ // I assume upvote is checkbox
                        viewHolder.upvote.setChecked(true)
                        viewHolder.upCount.setText("1");
                    }
                    else{
                       viewHolder.upvote.setChecked(false)
                        viewHolder.upCount.setText("0");
                    }
                }
            });

                holder.downvote.setTag(holder); // set tag to get clicked item view
                holder.downvote.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        PostsViewHolder viewHolder =(PostsViewHolder) v.getTag();
                        if(!v.isChecked()){ // I assume upvote is checkbox
                            viewHolder.downvote.setChecked(true)
                            viewHolder.downCount.setText("1");
                        }
                        else{
                           viewHolder.downvote.setChecked(false)
                            viewHolder.downCount.setText("0");
                        }
                    }
                });
    }

below method is importent for your problem in adapter class

@Override public int getItemViewType(int position) { 
        return position; 
} 

Edit

<CheckBox 
 android:id="@+id/upvote"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" 
 android:button="@drawable/uvselector" />

where drawable/uvselector.xml like

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_checked="false"
  android:drawable="@drawable/YOUR DISABLED UPVOTE IMAGE" />
 <item android:state_checked="true"
  android:drawable="@drawable/YOUR UPVOTE IMAGE" />
</selector>

where drawable/dvselector.xml like

<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_checked="false"
  android:drawable="@drawable/YOUR DISABLED DOWNVOTE IMAGE" />
 <item android:state_checked="true"
  android:drawable="@drawable/YOUR DOWNVOTE IMAGE" />
</selector>

Upvotes: 1

Akshay Bhat &#39;AB&#39;
Akshay Bhat &#39;AB&#39;

Reputation: 2700

Since recyclerView Items are recycled, you need to reset the state of the card everytime. In onBindViewHolder() reset all your views first to initial state and then do set other data. Like :

@Override
public void onBindViewHolder(final PostsViewHolder holder, int position) {
    resetViews(); // this method resets all your view to initial state you want
    setData(); // Setting current item data.
}

Upvotes: 0

Related Questions