Yamashiro Rion
Yamashiro Rion

Reputation: 1976

RecyclerView item holders have link to the same object in the memory

I faced with a strange issue. I have a RecyclerView, in which items can be removed. So I have the following code:

holder.deleteIcon.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        holder.deleteIcon.setEnabled(false);
        items.remove(holder.getAdapterPosition());
        notifyItemRemoved(holder.getAdapterPosition());
        notifyItemRangeChanged(holder.getAdapterPosition(), items.size());
    }
});

And everything goes okay, until I have many holder items. Then, when I remove an item, it seems that deleteIcon also disables at another holder item, so I can't remove another item.

I did some research and found that some holders have a link to the same object in the memory. I have printed the following logs:

Log.d(TAG, "onBindViewHolder: holder: " + holder);
Log.d(TAG, "onBindViewHolder: holder.deleteIcon: " + holder.deleteIcon);

And found that, e.g. 0 and 10th items have the same link (there are 40 items total):

onBindViewHolder: holder: ViewHolder{feba8d0 position=0 id=-1, oldPos=-1, pLpos:-1 no parent}
onBindViewHolder: holder.deleteIcon: android.widget.LinearLayout{5a670c9 V.E...C.. .......D 948,67-1068,157 #7f09006a app:id/deleteIcon}

onBindViewHolder: holder: ViewHolder{feba8d0 position=10 id=-1, oldPos=-1, pLpos:-1 no parent}
onBindViewHolder: holder.deleteIcon: android.widget.LinearLayout{5a670c9 V.E...C.. .......D 948,67-1068,157 #7f09006a app:id/deleteIcon}

So removing 0 item leads to disabling 10th item's deleteIcon.

Is that normal behavior of RecyclerView? How can I avoid a joint using of RecyclerView.ViewHolder object?

Upvotes: 0

Views: 107

Answers (2)

anchit
anchit

Reputation: 9

Try not to use getAdapterPosition() instead use the position provided in the bindViewHolder() Method.

Also, you should enable the icon with some model so that other models don't get mixed up

Setting directly a value to holder will lead to modification in many values.

Upvotes: 1

MichaelStoddart
MichaelStoddart

Reputation: 5639

You would need to re-enable the delete icon after the item had been removed, otherwise when the ViewHolder gets re-used the icon would still technically be disabled, even though the data inside is different.

A good way to do it would be to have an enabled boolean in your model class and in your onBindViewHolder have:

holder.deleteIcon.setEnabled(modelClass.isEnabled);

this could then be enabled or disabled with:

modelClass.isEnabled = true/false;
notifyItemChanged();

Upvotes: 1

Related Questions