Recycler NetworkImageView向前和向后滚动,内存不足和调整大小问题 [英] Recycler NetworkImageView Scrolling back and forward, out of memory and resizing issues

查看:162
本文介绍了Recycler NetworkImageView向前和向后滚动,内存不足和调整大小问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Recycler视图水平添加图库中的图像,如下所示。我能够彼此相邻地添加图像。

I am working to add an image from the gallery horizontally using recycler view as follows. I could able to add images next to each other.

以下代码可以正常运行,但有时会由于内存不足而崩溃。

The following code works but crashes sometimes because of out of memory concerns.

RecyclerViewAdapter ,我正在调用setSelectedPic方法加载图片。

RecyclerViewAdapter, I am calling setSelectedPic method to load the image.

@Override
public void onBindViewHolder(final ListViewHolder holder, int position) {
    PostProductImageLIst item = mItems.get(position);
    ImageUtil.setSelectedPic(holder.imgViewIcon, item.getPath());
}

ImageUtil Class

public static void setSelectedPic(CustomNetworkImageView view, String url) {
        Context context = view.getContext();
        ImageLoader imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
        if (!TextUtils.isEmpty(url)) {
            if (url.startsWith("http")) {
                imageLoader.get(url, ImageLoader.getImageListener(view,
                        R.drawable.image, android.R.drawable
                                .ic_dialog_alert));
                view.setImageUrl(url, imageLoader);
            } else {
                try {
                    Uri uri = Uri.parse(url);
                    InputStream is = context.getContentResolver().openInputStream(uri);
                    Bitmap bitmap = BitmapFactory.decodeStream(is);
                    view.setLocalImageBitmap(bitmap);
                    if (is!=null) {
                        is.close();
                    }
                } catch (Exception ex) {
                    Log.e("Image", ex.getMessage(), ex);
                }
            }
        } else {
            view.setImageUrl("", CustomVolleyRequest.getInstance(view.getContext()).getImageLoader());
        }
    }

然后我决定调整图像大小以解决问题aferomentioned问题,内存不足 - 。以下代码有效。但是,当我滚动回第一张图像时,该图像显示为空白或白色,但当我删除第二张图像时,我能够看到第一张图像。我无法弄清楚问题的根源。我正在使用NetworkImageView。

And then I decide to resize the images to solve the aferomentioned issue, out of memory-.The following code works. BUT, when I scroll back to first image, that image shows blank or white, but when I delete the second image, then I could able to see first image. I could not able to figure out the root of the problem. I am using NetworkImageView.

RecyclerViewAdapter ,我正在调用setSelectedPic方法来加载图片。

RecyclerViewAdapter, I am calling setSelectedPic method to load the image.

@Override
public void onBindViewHolder(final ListViewHolder holder, int position) {
    PostProductImageLIst item = mItems.get(position);
    ImageUtil.setSelectedPic(holder.imgViewIcon, item.getPath());
}

ImageUtil Class

public static void setSelectedPic(CustomNetworkImageView view, String url) {
        Context context = view.getContext();
        ImageLoader imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
        if (!TextUtils.isEmpty(url)) {
            if (url.startsWith("http")) {
                imageLoader.get(url, ImageLoader.getImageListener(view,
                        R.drawable.image, android.R.drawable
                                .ic_dialog_alert));
                view.setImageUrl(url, imageLoader);
            } else {
                try {
                int targetW = view.getWidth();
                int targetH = view.getHeight();
                Uri uri = Uri.parse(url);
                InputStream is = context.getContentResolver().openInputStream(uri);
                BitmapFactory.Options bmOptions = new BitmapFactory.Options();
                bmOptions.inJustDecodeBounds = true;

                BitmapFactory.decodeFile(url, bmOptions);
                int photoW = bmOptions.outWidth;
                int photoH = bmOptions.outHeight;

                // Determine how much to scale down the image
                int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
                // Decode the image file into a Bitmap sized to fill the View
                bmOptions.inJustDecodeBounds = false;
                bmOptions.inSampleSize = scaleFactor;
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                Matrix matrix = new Matrix();
                matrix.postRotate(getImageOrientation(url));
                Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),bitmap.getHeight(), matrix, true);
                view.setLocalImageBitmap(rotatedBitmap);
                if (is!=null) {
                    is.close();
                } catch (Exception ex) {
                    Log.e("Image", ex.getMessage(), ex);
                }
            }
        } else {
            view.setImageUrl("", CustomVolleyRequest.getInstance(view.getContext()).getImageLoader());
        }
    }


推荐答案

你应该缩放您的位图并使用缓存来减少加载时间。在此存储库中此处我已经提供了用于通过缩放和接近图像加载的参考代码缓存。

You should scale your Bitmap and use caching for reducing loading time. Here on this repository I've put reference code for approaching image loading with scaling and caching.

我在这里报告用于setPic方法的代码。这实际上使用LruCache来改进滚动时的位图加载。这可能是一个很好的起点。另请注意,Bitmap在放入缓存之前会进行缩放。

I report here code to be used for setPic method. This essentially uses an LruCache for improving Bitmap loading while scrolling. This could be a good starting point. Notice also that Bitmap are scaled before putting them in cache.

private static final int WIDTH = 100;

private LruCache<String, Bitmap> mMemoryCache;

public void setPic(MyImageView view, String url) {
    Context context = view.getContext();
    if (!TextUtils.isEmpty(url)) {
        if (url.startsWith("http")) {
            view.setImageUrl(url, VolleyHandler.getInstance(context).getImageLoader());
        } else {
            try {
                Uri uri = Uri.parse(url);
                Bitmap bitmap = mMemoryCache.get(url);
                if (bitmap == null) {
                    InputStream is = context.getContentResolver().openInputStream(uri);
                    bitmap = BitmapFactory.decodeStream(is);
                    Bitmap scaled = ImageUtils.getInstance().scaleBitmap(bitmap);
                    mMemoryCache.put(url, scaled);
                    if (is!=null) {
                        is.close();
                    }
                }
                view.setLocalImageBitmap(bitmap);
            } catch (Exception ex) {
                Log.e("Image", ex.getMessage(), ex);
            }
        }
    } else {
        view.setImageUrl("", VolleyHandler.getInstance(view.getContext()).getImageLoader());
    }
}

public Bitmap scaleBitmap(Bitmap bitmap) {
    int width = WIDTH;
    int height = (WIDTH * bitmap.getHeight()) / bitmap.getWidth();
    return Bitmap.createScaledBitmap(bitmap, width, height, false);
}

我建议也参考Android开发者文档这里(用于高效的位图加载)和这里(用于使用Volley进行位图缓存)。

I suggest also to refer to Android Developers documentation here (for efficient Bitmap loading) and here (for Bitmap caching with Volley).

这篇关于Recycler NetworkImageView向前和向后滚动,内存不足和调整大小问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆