We have a customised base class for creating a single cell inside a recyclerview:
public abstract class RecyclerViewItem<T extends RecyclerViewAdapter.ViewHolder> implements RecyclerViewItemInterface<T> {
@Override
public int getTypeId() {
return this.getClass().hashCode();
}
@Override
public T createViewHolder(ViewGroup parent) {
View v = LayoutInflater.from(parent.getContext()).inflate(getViewId(), parent, false);
try {
String className = ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0].toString().split("\\s")[1];
return (T)Class.forName(className).getConstructor(this.getClass(), View.class).newInstance(this, v);
} catch (Exception e) {
throw new RuntimeException("please create a viewholder accepting view as arg");
}
}
@Override
public void populateViewHolder(SdRecyclerViewAdapter.ViewHolder holder) {
onPopulateViewHolder((T) holder);
}
protected abstract int getViewId();
protected abstract void onPopulateViewHolder(T holder);
}
The interface:
public interface RecyclerViewItemInterface<T extends RecyclerViewAdapter.ViewHolder> {
int getTypeId();
T createViewHolder(ViewGroup parent);
void populateViewHolder(RecyclerViewAdapter.ViewHolder holder);
}
One of implementation of this class is using SimpleDraweeView to show image. I already set placeholder via:
holder.iconButton.getHierarchy().setPlaceholderImage(R.drawable.no_photo);
And if this cell has an image, display it:
mImageUrl = data.generateImageUrl();
if (mImageUrl != null) {
holder.iconButton.setImageURI(Uri.parse(imageUrl));
}
This correctly shows image for cell which has image. But if a cell has no image (mImageUrl null
), it randomly shows image from another cell.
I know I can just type:
if (mImageUrl != null) {
holder.iconButton.setImageURI(Uri.parse(imageUrl));
} else {
holder.iconButton.setImageURI("res:/" + R.drawable.no_photo);
}
Could somebody explain to me why Fresco seems like randomly choose the image it want to display if I do not call .setImageURI()
?
Thanks in advance.
I guess this happens because of view recycling. The recycler view re-uses an existing DraweeView, which still has the URL for the previous image set. That's why instead of
mImageUrl = data.generateImageUrl();
if (mImageUrl != null) {
holder.iconButton.setImageURI(Uri.parse(mImageUrl));
}
you can just do
mImageUrl = data.generateImageUrl();
holder.iconButton.setImageURI(mImageUrl != null ? Uri.parse(mImageUrl) : null);