Recently I use RecyclerView and add a custom header view (another type of item view) and try to updated it when data has changed. Something strange happens. The adapter crea
Here are a few issues with your implementation:
getItemCount expects the count of all items in the recyclerview including the header so you should return mItemList.size() + 1
the position field in onBindViewHolder() refers to the position of an element in the whole recyclerview including the header. so to bind a non-header item you will do something like item = mItemList.get(position - 1)
-- this won't fail because getItemViewType returns a number greater than 0 for TYPE_ITEMs
By doing so, notifyItemChanged should behave as expected
More cleaner solution (is not bug in animator, but this is a feature of layout manager):
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 5, LinearLayoutManager.VERTICAL, false){
@Override
public boolean supportsPredictiveItemAnimations() {
return false;//super.supportsPredictiveItemAnimations();
}
});
RecyclerView use both of ViewHolder for smooth animation from an old state to a new. This is default behaviour of RecyclerView.ItemAnimator.
You can disable animation by passing an empty item animator to RecyclerView:
listView.setItemAnimator(null);
To avoid ViewHolder's recreating and without disabling smooth animation after call recyclerView.notifyItemChanged() you can set DefaultItemAnimator and override canReuseUpdatedViewHolder() method.
Kotlin:
val itemAnimator: DefaultItemAnimator = object : DefaultItemAnimator() {
override fun canReuseUpdatedViewHolder(viewHolder: RecyclerView.ViewHolder): Boolean {
return true
}
}
recyclerView.itemAnimator = itemAnimator
You can also use notifyItemChanged with a payload: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#notifyitemchanged. It will reuse the same ViewHolder instance: "if the item is already represented by a ViewHolder and it will be rebound to the same ViewHolder"
((SimpleItemAnimator) myRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);