How to Avoid That RecyclerView’s Views are Blinking when notifyDataSetChanged()
At our android application, we sometimes need to refresh (e.g user swipe to refresh content) all cell items but generally there are a few new items, most of them are still the same data. However, when we refreshed the
RecyclerView
bynotifyDataSetChanged()
, it is blinking for a short time, especially strange on cell’s inner image view.
This is because RecycleView disabled stable IDs as default. So generally after notifyDataSetChanged(), RecyclerView.Adapter didn’t assigned the same ViewHolder to original item in the data set.
To solve this issue, we need to reuse the same ViewHolder and view for the same item. Here we use stable IDs for RecyclerView as solution.
To use stable IDs, we need to
- setHasStableIds(true)
InRecyclerView.Adapter
, we need to setsetHasStableIds(true)
; true means this adapter would publish a unique value as a key for item in data set. Adapter can use the key to indicate they are the same one or not after notifying data changed. - override getItemId(int position)
Then we must overridegetItemId(int position)
, to return identified long for the item at position. We need to make sure there is no different item data with the same returned id.
For example, it’s not recommended to do as following example because this item id changes by position, not the content.
@Override
public long getItemId(int position) {
return position;
}
So we need to override the getItemId() to return the same id if the content is identical, here is pseudocode:
@Override
public long getItemId(int position) {
Product product = mProductList.get(position);
return product.pid;
}
After using stable Id, RecyclerView would try to use the same viewholder and view for the same id. This would reduce blinking issue after data changed.