9

アダプター内でターゲットを使用するのに大きな問題があります。コードに関するドキュメントについて混乱しています

このクラスを実装するオブジェクトは、適切な内部ストレージのために {@link #equals(Object)} および {@link #hashCode()} の実用的な実装を持っている必要があります。このインターフェイスのインスタンスも比較され、ビューのリサイクルが発生しているかどうかが判断されます。アダプターで使用する場合は、このインターフェイスをカスタム ビュー タイプに直接追加して、正しいリサイクル動作を確保することをお勧めします。

この方法でターゲットを使用しようとしています:

class CustomTarget implements Target {
    private ImageView imageView;

    public CustomTarget(ImageView imageView) {
        this.imageView = imageView;
    }

    @Override
    public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
        imageView.setImageDrawable(new RoundedAvatarDrawable(bitmap));
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {
        imageView.setImageDrawable(errorDrawable);
    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {
        imageView.setImageDrawable(placeHolderDrawable);
    }

    @Override
    public boolean equals(Object o) {
        return imageView.equals(o);
    }

    @Override
    public int hashCode() {
        return imageView.hashCode();
    }
}

 @Override
public View getView(int position, View v, ViewGroup parent) {
....
    RoundedAvatarDrawable r = new RoundedAvatarDrawable(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_avatar_seahorse));
    ImageCacheController.with(mContext).getPicasso().load(member.getPicture_url()).resize(100, 100).centerCrop().placeholder(r).error(r).into(new CustomTarget(viewHolder.ivAvatar));
....
}

それは機能せず、画像は互いにランダムに変化します

4

2 に答える 2

12

関数全体を表示していないgetViewため、viewHandler の使用方法を知らなくても、何が起こっているのかを以下に示します。

あなたの問題は、呼び出されるCustomTargetたびに新しいものを作成していることです。getViewあなたはオブジェクトを持つという点に反対していTargetます。詳しく説明しましょう。

新しいダウンロード要求が行われると、同じターゲットへの以前の要求が停止されるか、ターゲットのコールバックが呼び出されなくなります。(したがって、ターゲットがリスト内の別の行に再利用された場合、両方の行の画像は取得されません)。

リクエストごとに新しいオブジェクトを使用しており、ピカソに、いわば各リクエストが異なる行に対するものであることを効果的に示唆しています。ドキュメントには、「このインターフェイスのインスタンスも比較されて、ビューのリサイクルが発生しているかどうかが判断されます」と記載されているため、各リクエストには新しく作成されたCustomTargetオブジェクトがあるため、2 つのリクエストが同じオブジェクトを持つことはなく、行のリサイクルは検出されません。

viewHolder も使用しています。この場合、viewHolder はTargetインターフェイスを拡張する必要があると思います (行ごとに 1 つの画像しかない場合)。このようにして、ダウンロードを要求するたびに、新しいオブジェクトを作成せずに同じオブジェクトを使用できます。

CustomTargetまた、 your の実装をの実装に委任していますImageViewequalsImageViewとhashCode関数が Picasso が要求する要件を満たしていることを確認してください。

equalsとの実装方法に関する情報hashCode: Java で equals と hashCode をオーバーライドするときに考慮すべき問題は何ですか?

于 2013-11-25T17:53:52.997 に答える
0

equals メソッドが壊れているようです。イメージビューをカスタム ターゲットと比較しています。これはそれを修正するかもしれません:

public boolean equals(Object o) {
    if(o instanceof CustomTarget) {
        return ((CustomTarget) o).imageView.equals(this.imageView);
    }
    return super.equals(o);
}
于 2014-09-02T09:26:59.103 に答える