Clive Jefferies Clive Jefferies - 5 months ago 138
Android Question

RecyclerView disappearing images

What I am trying to create is a horizontal scrolling image gallery. I have a RecyclerView (support 22.0.0). The problem I am having is that when I scroll to the end and then scroll back, usually one image will be missing sometimes two. Strangely when I keep swiping back and forth, a different image could be missing. Here is the layout for the item:



Here is the Adaper:

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder> {
private String[] mDataset;

public static class ViewHolder extends RecyclerView.ViewHolder {

public ImageView mImageView;
public ViewHolder(View v) {
mImageView = (ImageView) v.findViewById(;

public TestAdapter(String[] myDataset) {
mDataset = myDataset;

public TestAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.variaton_list_item, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;

public void onBindViewHolder(ViewHolder holder, int position) {

String url = mDataset[position];
Log.i("TEST", "position = " + position);
((MainActivity)MainActivity.getInstance()), holder.mImageView);

public int getItemCount() {
return mDataset.length;

The download method fetches the image, from a URL or gets it from the memory if it has been cached. This works fine in all other layouts e.g. ListView or GridView. Here is the code I use to set it up in the Fragment:

final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());

This is in the onCreateView method. When I get the urls I populate them and set the adapter using:

myDataset[i] = imageURL; // for each image
mAdapter = new TestAdapter(myDataset);

The interesting thing is the line in the onBindViewHolder method in the adapter, where I log the position. What I have found is that cells where the image is not shown is that this method is not being called. It is like it is skipping that cell for some reason. Even stranger, if I hold a cell and keep swiping from left to right, if a cell goes off screen and then comes back in, its image as gone as again the onBindViewHolder method is not called.


The one class that I did not think would matter was the one that was causing the issue. I am not sure what the reason is, but it resides in a custom ImageView class that I am using for recycling that I got from the BitmapFun sample.

    public class RecyclingImageView extends ImageView {

    public RecyclingImageView(Context context) {

    public RecyclingImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

     * @see android.widget.ImageView#onAttachedToWindow()
    protected void onAttachedToWindow() {}

     * @see android.widget.ImageView#onDetachedFromWindow()
    protected void onDetachedFromWindow() {
        // This has been detached from Window, so clear the drawable



     * @see android.widget.ImageView#setImageDrawable(
    public void setImageDrawable(Drawable drawable) {
        // Keep hold of previous Drawable
        final Drawable previousDrawable = getDrawable();

        // Call super to set new Drawable

        // Notify new Drawable that it is being displayed
        notifyDrawable(drawable, true);

        // Notify old Drawable so it is no longer being displayed
        notifyDrawable(previousDrawable, false);

     * Notifies the drawable that it's displayed state has changed.
     * @param drawable
     * @param isDisplayed
    private static void notifyDrawable(Drawable drawable, final boolean isDisplayed) {
        if (drawable instanceof RecyclingBitmapDrawable) {
            // The drawable is a CountingBitmapDrawable, so notify it
            ((RecyclingBitmapDrawable) drawable).setIsDisplayed(isDisplayed);
        } else if (drawable instanceof LayerDrawable) {
            // The drawable is a LayerDrawable, so recurse on each layer
            LayerDrawable layerDrawable = (LayerDrawable) drawable;
            for (int i = 0, z = layerDrawable.getNumberOfLayers(); i < z; i++) {
                notifyDrawable(layerDrawable.getDrawable(i), isDisplayed);


When I replace this with a normal ImageView, I no longer get the problem.