1

そのため、リサイクラー ビューを使用して画像をグリッドに表示し、ボレー ライブラリを使用して URL からビットマップとして画像をダウンロードしています。

public void onBindViewHolder(final TrendingAdapter.ViewHolder viewHolder, int i) {
    ImageRequest request = new ImageRequest(url, new Response.Listener<Bitmap>() {
        @Override
        public void onResponse(Bitmap bitmap) {
            if (bitmap != null) {
                viewHolder.getmImageView().setImageBitmap(bitmap);
            }
        }
    }, 0, 0, null,
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {
                }
            });
    AppController.getInstance().addToRequestQueue(request);
}

問題は、画像がダウンロードされる前に1つ以上のビューをスクロールしてスキップし、そのビューがリサイクルされると、それらの中間ビューで画像のダウンロード要求がキャンセルされず、実際の画像がダウンロードされる前にその/それらの画像のフラッシュが発生することですそのビューにロードされます。

そのため、タグを使用してこれらの中間画像リクエストをキャンセルすることを考えましたが、他の並列ビューでもリクエストがキャンセルされるため、方法がわかりません!

また、ボレーNetworkImageView(そのような画像のキャンセルを単独で処理する)を使用すると、完璧な結果が得られます。しかし、すべての画像のビットマップを取得して色を選択する必要があるため、NetworkImageView を使用できません。

Q) recyclerview を使用して膨らませた特定のイメージビューで、保留中のすべてのボレー イメージ リクエスト (ロードする必要があり、他の並列ビューに影響を与えないものを除く) をキャンセルするにはどうすればよいですか?

4

4 に答える 4

8

ImageLoaderにリクエストを直接追加する代わりに、クラスを使用する必要がありRequestQueueます。そうget()すれば、画像を取得するために使用されるメソッドは、 type のオブジェクトを返しますImageContainer

ImageContainerこれを に保存ViewHolderし、ビューが再利用されたときcancelRequest()に、再利用された画像に対してメソッドを呼び出して、まだ実行されていない場合は、再利用された画像のリクエストをキャンセルします。

NetworkImageViewのコードを見てください。同様の方法で機能します。

于 2014-10-27T22:06:46.460 に答える
1

私は問題を解決しました!yaaeeye :D @Itai の答えは正しい方向に私を指摘しました。NetworkImageView のコードをよく見て、必要に応じて修正しました。だから私は CustomNetworkImageView を作りました

public class CustomNetworkImageView extends ImageView {

    // Added code block start

    public interface ResponseObserver {
        public void onError();

        public void onSuccess();
    }

    private ResponseObserver mResponseObserver;

    public void setmResponseObserver(ResponseObserver observer) {
        mResponseObserver = observer;
    }

    private Bitmap bmp = null;

    // Added code block end

    private String mUrl;

    private int mDefaultImageId;

    private int mErrorImageId;

    private ImageLoader mImageLoader;

    public CustomNetworkImageView(Context context) {
        this(context, null);
    }

    public CustomNetworkImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setImageUrl(String url, ImageLoader imageLoader) {
        mUrl = url;
        mImageLoader = imageLoader;
        loadImageIfNecessary();
    }

    public void setDefaultImageResId(int defaultImage) {
        mDefaultImageId = defaultImage;
    }

    public void setErrorImageResId(int errorImage) {
        mErrorImageId = errorImage;

        // Added code block start

        if (mResponseObserver != null) {
            mResponseObserver.onError();
        }

        // Added code block end

    }

    // Added code block start

    public Bitmap getBitmap() {
        return bmp;
    }

    // Added code block end

    private void loadImageIfNecessary() {
        int width = getWidth();
        int height = getHeight();

        if (width == 0 && height == 0) {
            return;
        }

        if (TextUtils.isEmpty(mUrl)) {
            ImageContainer oldContainer = (ImageContainer) getTag();
            if (oldContainer != null) {
                oldContainer.cancelRequest();
                setImageBitmap(null);
            }
            return;
        }

        ImageContainer oldContainer = (ImageContainer) getTag();

        if (oldContainer != null && oldContainer.getRequestUrl() != null) {
            if (oldContainer.getRequestUrl().equals(mUrl)) {

                return;
            } else {

                oldContainer.cancelRequest();
                setImageBitmap(null);
            }
        }

        ImageContainer newContainer = mImageLoader.get(mUrl,
                ImageLoader.getImageListener(this, mDefaultImageId, mErrorImageId));

        setTag(newContainer);

        final Bitmap bitmap = newContainer.getBitmap();
        if (bitmap != null) {

            setImageBitmap(bitmap);

           // Added code block start

            bmp = bitmap;
            if (mResponseObserver != null) {
                mResponseObserver.onSuccess();
            }

           // Added code block end
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        loadImageIfNecessary();
    }

    @Override
    protected void onDetachedFromWindow() {
        ImageContainer oldContainer = (ImageContainer) getTag();
        if (oldContainer != null) {

            oldContainer.cancelRequest();
            setImageBitmap(null);

            setTag(null);
        }
        super.onDetachedFromWindow();
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        invalidate();
    }
}

CustomNetworkImageView の使用:

    viewHolder.getmImageView().setImageUrl(wallThumb.get(i), AppController.getInstance().getImageLoader());

    viewHolder.getmImageView().setmResponseObserver(new CustomNetworkImageView.ResponseObserver() {

            @Override
            public void onError() {
            }

            @Override
            public void onSuccess() {
                // Image is loaded in ImageView.. Do Something..
                Bitmap bitmap = viewHolder.getmImageView().getBitmap();
            }
        });

SetmResponseObserver は、ビットマップが ImageView にロードされているかどうかをリッスンし、タスクが完了した場合に onSuccess が呼び出されます。また、イメージ ビューでビットマップを返し、次のように使用できる関数も作成しました。

Bitmap bmp = viewHolde.getmImageView.getBitmap();

私はAndroidが初めてなので、何か間違ったことをした場合は、お気軽にコメントして修正してください。やぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁ

于 2014-10-28T06:41:20.223 に答える
0
public class RecyclerViewPagerNetworkImageView extends NetworkImageView {
public RecyclerViewPagerNetworkImageView(Context context) {
    super(context);
}

public RecyclerViewPagerNetworkImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public RecyclerViewPagerNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
protected void onDetachedFromWindow() {
    // delete
    /*if (mImageContainer != null) {
        // If the view was bound to an image request, cancel it and clear
        // out the image from the view.
        mImageContainer.cancelRequest();
        setImageBitmap(null);
        // also clear out the container so we can reload the image if necessary.
        mImageContainer = null;
    }
    super.onDetachedFromWindow();*/
}

}

于 2015-10-12T11:36:33.927 に答える