To prevent the crash from this issue, you need to call setHasStableIds(boolean)
from your adapter and pass the parameter as true:
adapter.setHasStableIds(true);
Explanation:
The problem occurs when you call adapter.notifyDataSetChanged();
The recyclerView
then calls detachAndScrapAttachedViews(recycler);
It temporarily detaches and scraps all currently attached child views. Views will be scrapped into the given Recycler
. The Recycler
may prefer to reuse scrap views.
Then scrapOrRecycleView(recycler, (int) position, (View) child);
is called. This function checks if "hasStableIds" is true or false. If its false then you get the following error :
"Scrapped or attached views may not be recycled."
Stable IDs allow the View
(RecyclerView
, ListView
, etc.) to optimize for the case when items remain the same between notifyDataSetChanged
calls.
hasStableIds() == true
indicates whether the item ids are stable across changes to the underlying data.
If the item ids are stable then it can be reused by the view i.e. "recycled" making the process of re-rendering after the call to notifyDataSetChanged()
efficient. If item ids are not stable, there is no guarantee that the item has been recycled as there is no way to track them.
Note: Setting setHasStableIds()
to true is not a way to request stable IDs, but to tell Recycler/List/Grid Views that you are providing the said stability.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…