I'm trying to make a notifyDataSetChanged inside onBindViewHolder once picasso callback has beening triggered but i always have this error
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout
The reason why i need to do that is because i'm using a StaggeredGridLayoutManager so the recyclerview need to be reordered after picasso loaded the images with different sizes
My actual code is :
@Override
public void onBindViewHolder(filmsAdapter.ViewHolder holder, int position) {
FilmInfo filmInfo = filmsList.get(position);
Picasso.get()
.load(filmInfo.GetPreviewImageUrl())
.placeholder(R.drawable.ic_launcher)
.into(holder.getFilmItemIcon(), new Callback() {
@Override
public void onSuccess() {
notifyDataSetChanged();
}
@Override
public void onError(Exception e) {
}
});
holder.getItemContainer().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, MainActivity.class);
intent.putExtra("filmInfo", filmInfo);
view.getContext().startActivity(intent);
}
});
}
About the problem you can use ReclyclerView.isComputingLayout() to check whenever the RecyclerView is still computing the layout.
But, since Picasso loads images asynchronously, it will generate a infinite loop. When the Picasso.onSuccess triggers notifyDataSetChanged the onBindViewHolder will be called again, and so on.
The only solution would be if you can keep track of how many images must be loaded or to use a semaphore if you know how many entries must be processed, but if the number of items in the list is undefined then will not be easy as the onBindViewHolder will get called every time the user scrolls the RecyclerView.
So, the overall problem is that Picasso.onSuccess will call notifyDataSetChanged, and notifyDataSetChanged will call again onBindViewHolder which will trigger again Picasso.