There are more than 200 items in my list. RecyclerView is updated regularly (Every 10 seconds) . RecyclerView blocking ui thread for few seconds during updates. I'm using notifyDataSetChanged
method for refresh recyclerview. Is there another way to prevent freezing ? By the way I don't want use pagination.
This method run every 10 seconds :
public void refreshAssetList(List<Asset> newAssetList){
recyclerViewAdapter.setAssetList(newAssetList);
recyclerViewAdapter.notifyDataSetChanged();
}
RecyclerViewAdapter class :
public class AssetListRecyclerViewAdapter extends RecyclerView.Adapter<AssetListRecyclerViewAdapter.BaseViewHolder> {
private List<Asset> assetList;
Context context;
public AssetListRecyclerViewAdapter(List<Asset> assetList, Context context) {
this.assetList = assetList;
this.context = context;
}
public void setAssetList(List<Asset> assetList) {
this.assetList = assetList;
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_asset, null);
return new DetailViewHolder(itemLayoutView);
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
Asset asset = assetList.get(position);
Last last = asset.getLast();
if (holder.getItemViewType() == TYPE_DETAIL) {
DetailViewHolder mHolder = (DetailViewHolder) holder;
mHolder.dateTextView.setText(last.getDate());
mHolder.brandTextView.setText(asset.getMc());
}
}
class DetailViewHolder extends BaseViewHolder {
@Bind(R.id.brandTextV)
TextView brandTextView;
@Bind(R.id.dateTextV)
TextView dateTextView;
DetailViewHolder(View itemLayoutView) {
super(itemLayoutView);
ButterKnife.bind(this, itemLayoutView);
}
}
}
Perform the action to update the adapter as:
After some research I found DiffUtil class for updating list.
From the documentation :
DiffUtil needs new list and old list. It only updates changing items in list. I created AssetDiffUtil class as below :
Then I added swapItems method for refreshing list in AssetListRecyclerViewAdapter class.
That's it. But my problem still exist. Before using DiffUtil freezing time 4 seconds . Now, after using DiffUtil freezing time is 2 seconds. Unfortunately this is not a definitive solution for my problem.
You do not need to call
notifyDataSetChanged
, it's an expensive operation your wholeRecyclerView
will completely redraw, rebind etc.As the doc says:
All you need to do is loop through every position and if needed update desired item otherwise do nothing or skip.
What you should do:
As you are updating your whole view first you need to compare your (visible) adapter's
List<Asset>
with newList<Asset>
and retrieve only those items which you need to be update, once you have the list loop through updated list and update your adapter's view by usingviewAdapter.notifyItemChanged(position)
.