web-dev-qa-db-ja.com

Recyclerviewアダプターとグライド-4〜5行ごとに同じ画像

私にはこの問題があります-テスト目的のために、受け取ったリストからParseFileの1つにParseObjectを追加しました。その行にのみ表示するのではなく、4〜5行ごとに表示される場合があります。リサイクルの見方はこれと関係があると思います。奇妙なことに、(この例から削除された)他のデータはposition変数でうまく機能します。

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


        }

    }
35
jean d'arme

ここでの答えは間違っていますが、正しい軌道に乗っています。

Drawableをnullに設定するだけでなく、Glide#clear()を呼び出す必要があります。 clear()を呼び出さない場合、非同期ロードが順不同で完了すると、ビューのリサイクルの問題が発生する可能性があります。コードは次のようになります。

@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.clear(holder.imageView);
        // remove the placeholder (optional); read comments below
        holder.imageView.setImageDrawable(null);
    }
} 
73
Sam Judd

たぶん、あなたはこのような何かを試す必要があります

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

サンプル :

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

RecyclerViewでは、各行が新しいデータでリサイクルされます。コードでは、ImageViewでない場合にのみnullを設定し、それ以外は何もしません。この場合、nullではない場合、現在のオブジェクトに対してImageViewを実行しなかったため、overrideは古いイメージを表示します。これを修正するには、else条件を追加し、ImageViewをnull /空白に設定します。

@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);
        }
    } 
1
Sharj

アダプタにadapter.setHasStableIds(true)があり、getItemIdがオーバーライドされていないためだと思います。そのため、recyclerViewは同じIDを持つホルダーを見つけて再利用しようとします。

1
Pavlo Zorya

"logo"がnullの場合、リサイクルイメージをクリアする代わりに取得します。このコードを追加して、画像を適切に消去します。

holder.imageView.setImageDrawable(null);
1
BladeCoder