Search code examples
androidandroid-recyclerviewfresco

Fresco randomly set uri from cache if drawee view never call .setImageUri(uri)


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.


Solution

  • 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);