7

I'm having the following error in my app :

java.lang.IllegalStateException: Two different ViewHolders have the same stable ID. Stable IDs in your adapter MUST BE unique and SHOULD NOT change.
ViewHolder 1:ViewHolder{c7b44d1 position=5 id=3, oldPos=-1, pLpos:-1 not recyclable(1)} 
View Holder 2:ViewHolder{67232f6 position=3 id=3, oldPos=-1, pLpos:-1}

I'm using MaterialDrawer from Mike @github, this is my viewholder sample :

public class FavoritesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

TextView Title;
ImageView Pic;

public FavoritesViewHolder(View itemView) {
    super(itemView);
    itemView.setOnClickListener(this);
    Title = (TextView) itemView.findViewById(R.id.textViewHighlight);
    Pic = (ImageView) itemView.findViewById(R.id.imageViewHighlight);

   }
}

Two fragments are switching their layout, when i press the first, it load without any problem, when i press the second fragment, it load a different layout and FC itself.

Both fragmets use the same ViewHolder code but in different classes .

Jaeger
  • 1,646
  • 8
  • 27
  • 59
  • are you sure that your id are stable and unique for each item? – JAAD Jun 06 '16 at 05:47
  • Noobie question : Where to find that id ? i didn't come across any a similar thing at all. – Jaeger Jun 06 '16 at 05:51
  • 1
    check whether getItemId() return same for 2 viewholder, also check if you title same for 2 viewholders? – JAAD Jun 06 '16 at 05:53
  • Both Viewholders have different class name, I just modified the class code, used different variables names, it worked now, i don't think that's the problem but it's fixed now, thanks!. – Jaeger Jun 06 '16 at 06:06
  • 1
    the problem was 2 viewholder having same id you must be passing something that result in same id in 2 viewholder in the lib that was the issue – JAAD Jun 06 '16 at 06:09

2 Answers2

2

In my case I got this error when manipulated list items (changed their positions), but made a mistake. I tried to create a copy of an item and add it to the top:

val oldItem = adapter.getItem(id)
val newItem = oldItem.copy(text = "item updated")
adapter.removeItem(7) // Removed nothing.
adapter.addItem(0, newItem) // Added the item with the same id.

I wanted to remove the 7th item instead of the item with the given id. So, I didn't remove anything (removeItem works so in my code).Then I added a new item with the same id. Now the list contains two equal items and throws the error. So, correct an error to have unique ids.

If you don't know where equal ids appear, you can do this.

Set adapter.setHasStableIds(false) and after it assign an adapter of RecyclerView:

with(view.recycler_view) {
    layoutManager = this@YourFragment.layoutManager
    adapter = this@YourFragment.adapter
    setHasFixedSize(true)
}

If you set setHasStableIds(false) after RecyclerView, you will get an error.

These two ViewHolders can be of the same class, not different.

CoolMind
  • 26,736
  • 15
  • 188
  • 224
-2

remove your code setHasStableIds, because recyclerView has a reuse mechanism