Change selected in RecyclerView to update all rows

I am trying to get the functionality of a "like" button in my app like in Facebook. I want that whenever the user clicks a button like this, the drawing color on the button should change from gray to blue. I am using RecyclerView for feeds. Since the RecyclerView enforces the viewer template, the color of all such buttons changes after that. I would really appreciate some help with this problem.

This is the code for the adapter

public class FacebookTimelineAdapter : RecyclerView.Adapter
{
    Context mContext { get; set;}
    List<FacebookModel> mData;
    LayoutInflater inflater;
    FacebookViewHolder holder;

    public FacebookTimelineAdapter (Context context,List<FacebookModel> data)
    {
        this.mContext = context;
        this.mData = data;
        this.inflater = LayoutInflater.From (context);
    }

    #region implemented abstract members of Adapter
    public override void OnBindViewHolder (RecyclerView.ViewHolder viewholder, int position)
    {
        holder = viewholder as FacebookViewHolder;
        holder.userName.Text = mData [position].userName;
        holder.timestamp.Text = mData [position].timestamp;

        if(!(mData[position].profilePictureId==0) || !(mData[position].profilePictureId==null))
        holder.profilePicture.SetImageDrawable (mContext.Resources.GetDrawable(mData[position].profilePictureId));

        if (mData [position].feedMessage == "") {
            holder.feedMessage.Visibility = ViewStates.Gone;
        } else {
            holder.feedMessage.Visibility = ViewStates.Visible;
            holder.feedMessage.Text = mData [position].feedMessage;
        }


        if ((mData [position].feedUrl == "") || (mData [position].feedUrl ==null)) {
            holder.feedUrl.Visibility = ViewStates.Gone;
        } else {
            holder.feedUrl.Visibility = ViewStates.Visible;
            holder.feedUrl.Text = mData [position].feedUrl;
        }

        if ((mData [position].feedImage==null) || (mData [position].feedImage==0)) {
            holder.feedImage .Visibility = ViewStates.Gone;
        } else {
            holder.feedImage .Visibility = ViewStates.Visible;
            holder.feedImage.SetImageDrawable(mContext.Resources.GetDrawable(mData[position].feedImage)) ;
        }

        holder.like.Click += delegate {
            Drawable img = mContext.Resources.GetDrawable (Resource.Drawable.fb_comment);
            holder.like.SetCompoundDrawablesWithIntrinsicBounds (img, null, null, null);
        };



    }

    public override RecyclerView.ViewHolder OnCreateViewHolder (ViewGroup parent, int viewType)
    {

        return new FacebookViewHolder (inflater.Inflate (Resource.Layout.timeline_item_facebook,parent,false),this);

    }


    public override int ItemCount {
        get {
            return mData.Count;
        }
    }

    public void LikeClicked(int position)
    {
        Drawable img = mContext.Resources.GetDrawable (Resource.Drawable.fb_comment);
        holder.like.SetCompoundDrawablesWithIntrinsicBounds (img, null, null, null);

    }
    #endregion
}
}

      

This is the code for the ViewHolder

    public class FacebookViewHolder : RecyclerView.ViewHolder
    {
        public TextView userName,timestamp,feedUrl,feedMessage;
        public ImageView profilePicture,feedImage;
        public Button like, comment;


        public FacebookViewHolder(View item, FacebookTimelineAdapter adapter) : base(item)
        {
            userName=item.FindViewById<TextView>(Resource.Id.fb_userName);
            timestamp=item.FindViewById<TextView>(Resource.Id.fb_time);
            feedUrl=item.FindViewById<TextView>(Resource.Id.fb_feed_url);
            feedMessage=item.FindViewById<TextView>(Resource.Id.fb_feed_message);
            profilePicture=item.FindViewById<ImageView>(Resource.Id.fb_profilePicture);
            feedImage=item.FindViewById<ImageView>(Resource.Id.fb_feed_image);
            like=item.FindViewById<Button>(Resource.Id.fb_feed_like);
            comment=item.FindViewById<Button>(Resource.Id.fb_feed_comment);

        }

    }

      

The code is in C # since I am developing an Android app in Xamarin.

+3


source to share


2 answers


When using the recycling view template, you must "reset" the state of the reworked view to its original state, so you won't have changes made to one child applied to another when the view was checked back.



+1


source


I was working on the solution provided by Marcos.

This is my adapter

public class FacebookTimelineAdapter : RecyclerView.Adapter
{
    Context mContext { get; set;}
    List<FacebookModel> mData;
    LayoutInflater inflater;
    FacebookViewHolder holder;

    public FacebookTimelineAdapter (Context context,List<FacebookModel> data)
    {
        this.mContext = context;
        this.mData = data;
        this.inflater = LayoutInflater.From (context);
    }

    #region implemented abstract members of Adapter
    public override void OnBindViewHolder (RecyclerView.ViewHolder viewholder, int position)
    {
        holder = viewholder as FacebookViewHolder;
        holder.userName.Text = mData [position].userName;
        holder.timestamp.Text = mData [position].timestamp;

        if(!(mData[position].profilePictureId==0) || !(mData[position].profilePictureId==null))
        holder.profilePicture.SetImageDrawable (mContext.Resources.GetDrawable(mData[position].profilePictureId));

        if (mData [position].feedMessage == "") {
            holder.feedMessage.Visibility = ViewStates.Gone;
        } else {
            holder.feedMessage.Visibility = ViewStates.Visible;
            holder.feedMessage.Text = mData [position].feedMessage;
        }


        if ((mData [position].feedUrl == "") || (mData [position].feedUrl ==null)) {
            holder.feedUrl.Visibility = ViewStates.Gone;
        } else {
            holder.feedUrl.Visibility = ViewStates.Visible;
            holder.feedUrl.Text = mData [position].feedUrl;
        }

        if ((mData [position].feedImage==null) || (mData [position].feedImage==0)) {
            holder.feedImage .Visibility = ViewStates.Gone;
        } else {
            holder.feedImage .Visibility = ViewStates.Visible;
            holder.feedImage.SetImageDrawable(mContext.Resources.GetDrawable(mData[position].feedImage)) ;
        }

  // Made changes in data structure to see if the post was liked or not. 

    if (mData [position].liked) {
            Drawable img = mContext.Resources.GetDrawable (Resource.Drawable.fb_liked);
            holder.like.SetCompoundDrawablesWithIntrinsicBounds (img, null, null, null);
        } else {
            Drawable img = mContext.Resources.GetDrawable (Resource.Drawable.fb_like);
            holder.like.SetCompoundDrawablesWithIntrinsicBounds (img, null, null, null);
        }

    }

    public override RecyclerView.ViewHolder OnCreateViewHolder (ViewGroup parent, int viewType)
    {

        return new FacebookViewHolder (inflater.Inflate (Resource.Layout.timeline_item_facebook,parent,false),this);

    }


    public override int ItemCount {
        get {
            return mData.Count;
        }
    }

 // On Clicking the like button notifyItemChanged() is called
    public void LikeClicked(int position)
    {
        if (mData [position].liked)
            mData [position].liked = false;
        else
            mData [position].liked = true;

        NotifyItemChanged (position);

    }

      



This is my ViewHolder

 public class FacebookViewHolder : RecyclerView.ViewHolder
    {
        public TextView userName,timestamp,feedUrl,feedMessage;
        public ImageView profilePicture,feedImage;
        public Button like, comment;


        public FacebookViewHolder(View item, FacebookTimelineAdapter adapter) : base(item)
        {
            userName=item.FindViewById<TextView>(Resource.Id.fb_userName);
            timestamp=item.FindViewById<TextView>(Resource.Id.fb_time);
            feedUrl=item.FindViewById<TextView>(Resource.Id.fb_feed_url);
            feedMessage=item.FindViewById<TextView>(Resource.Id.fb_feed_message);
            profilePicture=item.FindViewById<ImageView>(Resource.Id.fb_profilePicture);
            feedImage=item.FindViewById<ImageView>(Resource.Id.fb_feed_image);
            like=item.FindViewById<Button>(Resource.Id.fb_feed_like);
            comment=item.FindViewById<Button>(Resource.Id.fb_feed_comment);

           // Added Click listener in Viewholder
            like.Click += delegate {
                adapter.LikeClicked(LayoutPosition);
            }; 
        }

    }

      

+3


source







All Articles