NotifyItemChanged (int position) updates multiple items in a RecyclerView

I am using RecyclerView to display a list of items, and I need to update the state for one item by position. I update my item in the list and then call notifyItemChanged (int position) as follows:

myList.set(position, newModifiedItem); notifyItemChanged(position); 

The item is updated successfully, but some other items are also randomly updated, and every time I look up and down the list of products, this update (a different icon state) is performed on other items.

I make changes to onBindViewHolder , where I check the position element by position and decide to set a different status.

Full adapter code:

 public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<MyObj> myList; public MyAdapter(List<MyObj> list) { this.myList = list; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_item, parent, false); return new ViewHolder(view); } public void onBindViewHolder(final ViewHolder holder, final int position) { MyObj myObj = myList.get(position); boolean isSpecial = myObj.getMySpecialStatus(); holder.myItemTitle.setText(myObj.getTitle()); //decide if item has different icon state if (isSpecial) { holder.myItemIcon.setImageResource(R.drawable.ic_special); } } @Override public int getItemCount() { return myList.size(); } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView myItemTitle; public ImageView myItemIcon; public LinearLayout itemClickable; //some other views public ViewHolder(View itemView) { super(itemView); myItemTitle = (TextView) itemView.findViewById(R.id.item_title); myItemIcon = (ImageView) itemView.findViewById(R.id.item_img); itemClickable = (LinearLayout) itemView.findViewById(R.id.item_clickable_zone); itemClickable.setOnClickListener(this); //some other views } @Override public void onClick(View v) { final int position = getAdapterPosition(); if (position != RecyclerView.NO_POSITION) { switch (v.getId()) { case R.id.item_clickable_zone: { //some logic to change status - here just an idea MyObj newModifiedItem = myList.get(position); newModifiedItem.setMySpecialStatus(true); myList.set(position, newModifiedItem); notifyItemChanged(position); break; } //some other views on click } } } } } 
+6
source share
2 answers

The problem is in your onBindViewHolder() , where you did not use the else argument for the if . It should be like:

 public void onBindViewHolder(final ViewHolder holder, final int position) { MyObj myObj = myList.get(position); boolean isSpecial = myObj.getMySpecialStatus(); holder.myItemTitle.setText(myObj.getTitle()); //decide if item has different icon state if (isSpecial) { holder.myItemIcon.setImageResource(R.drawable.ic_special); } else { //here is the trick - set normal state back holder.myItemIcon.setImageResource(R.drawable.ic_standard); } } 
+2
source

Try it,

 MyObj newModifiedItem = myList.get(position); //getting object from the list newModifiedItem.setMySpecialStatus(true); notifyItemChanged(position, newModifiedItem); 
+1
source

All Articles