46

I have this problem - just for testing purposes I added ParseFile to one of ParseObject from received list. Instead of showing it only in that row it shows every 4-5 rows, sometimes more, sometimes less. I supspect that recycling view have something to do with this. Strangely, other data (deleted from this example) works fine with position variable.

@Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        if(parseList.get(position).get("logo") != null){
            ParseFile image = (ParseFile) parseList.get(position).get("logo");
            String url = image.getUrl();
            Glide.with(context)
                    .load(url)
                    .placeholder(R.drawable.piwo_48)
                    .transform(new CircleTransform(context))
                    .into(holder.imageView);


        }

    }
4

5 回答 5

87

The answers here are incorrect, although they're on the right track.

You need to call Glide#clear(), not just set the image drawable to null. If you don't call clear(), an async load completing out of order may still cause view recycling issues. Your code should look like this:

@Override 
public void onBindViewHolder(ViewHolder holder, int position) {
    if (parseList.get(position).get("logo") != null) {
        ParseFile image = (ParseFile) parseList.get(position).get("logo");
        String url = image.getUrl();
        Glide.with(context) 
                .load(url)
                .placeholder(R.drawable.piwo_48)
                .transform(new CircleTransform(context)) 
                .into(holder.imageView);
    } else {
        // make sure Glide doesn't load anything into this view until told otherwise
        Glide.with(context).clear(holder.imageView);
        // remove the placeholder (optional); read comments below
        holder.imageView.setImageDrawable(null);
    }
} 
于 2015-09-24T16:39:35.567 回答
4

Maybe you need to try something like this

.signature(new StringSignature(String.valueOf(System.currentTimeMillis())))

sample :

Glide.with(context)
                .load(url)
                .placeholder(R.drawable.progress_animation)
                .crossFade()
                .signature(new StringSignature(String.valueOf(System.currentTimeMillis())))
                .error(R.drawable.image_error_404)
                .into(iv);
于 2017-02-15T11:23:36.747 回答
2

In RecyclerView each row is recycled with new data. In your code you are setting ImageView only when it's not null and otherwise doing nothing. In this case when it's not null ImageView will show old image since you didn't override for the current object. You can fix this by adding else condition and setting ImageView to null/blank anything.

@Override 
    public void onBindViewHolder(ViewHolder holder, int position) {
        if(parseList.get(position).get("logo") != null){
            ParseFile image = (ParseFile) parseList.get(position).get("logo");
            String url = image.getUrl();
            Glide.with(context) 
                    .load(url)
                    .placeholder(R.drawable.piwo_48)
                    .transform(new CircleTransform(context)) 
                    .into(holder.imageView);


        } 
        else{
            holder.imageView.setImageDrawable(null);
        }
    } 
于 2015-09-21T23:57:26.733 回答
1

When "logo" is null, you get the recycled image instead of clearing it. Add this code to properly clear the image:

holder.imageView.setImageDrawable(null);
于 2015-09-21T23:57:05.400 回答
1

I think it is because your adapter has adapter.setHasStableIds(true) is true and getItemId is not overridden. So recyclerView try to find holder with the same id and reuse it.

于 2018-07-19T15:15:15.507 回答