Android ListView异步加载图片

本文介绍了一个自定义的图片加载工具类ImagesLoader,该工具实现了图片资源的按需加载和缓存,通过使用LRU缓存策略提高图片加载效率,并提供了一种适配不同屏幕尺寸的图片压缩方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 图片加载工具
 * Created by lezg on 2014/7/24.
 */
public class ImagesLoader {

    private static ImagesLoader mIamesLoader;

    private LruCache<Integer, Bitmap> mMemoryCache;

    private ImagesLoader() {
        int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        // 设置图片缓存大小为程序最大可用内存的1/4
        int cacheSize = maxMemory / 4;
        mMemoryCache = new LruCache<Integer, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(Integer key, Bitmap bitmap) {
                return bitmap.getByteCount() / 1024;
            }
        };
    }

    /**
     * 获取 ImagesLoader实例
     *
     * @return ImagesLoader实例
     */
    public static ImagesLoader getInstance() {
        if (mIamesLoader == null) {
            mIamesLoader = new ImagesLoader();
        }
        return mIamesLoader;
    }

    /**
     * 将一张图片存储到LruCache中
     *
     * @param key    LruCache的键,这里传人图片资源的ID
     * @param bitmap LruCache的键bitmap
     */
    public void addBitmapToMemoryCache(int key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            mMemoryCache.put(key, bitmap);
        }
    }

    /**
     * 从LruCache中获取一张图片,如果不存在就返回null。
     *
     * @param key LruCache的键,这里传人图片资源的ID
     * @return 对应传入键的Bitmap对象,或者null。
     */
    public Bitmap getBitmapFromMemCache(int key) {
        return mMemoryCache.get(key);
    }

    /**
     * 获取压缩比率
     *
     * @param options
     * @param reqWidth  目标宽度
     * @param reqHeight 目标高度
     * @return 压缩比率
     */
    private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        int height = options.outHeight;
        int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            int heightRatio = Math.round((float) height / (float) reqHeight);
            int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

    /**
     * 对图片进行压缩
     *
     * @param mResources Resources
     * @param imageId    图片资源ID
     * @param reqWidth   目标宽度
     * @param reqHeight  目标高度
     * @return bitmap
     */
    public Bitmap decodeSampleBitmapFromResource(Resources mResources, int imageId, int reqWidth, int reqHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(mResources, imageId, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeResource(mResources, imageId, options);
        addBitmapToMemoryCache(imageId, bitmap);
        return bitmap;
    }
}



/**
 * GoogleCardsAdapter
 * Created by lezg on 2014/7/23.
 */
public class GoogleCardsAdapter extends BaseAdapter {

    private Context mContext;
    private ImagesLoader mImagesLoader;
    private ExecutorService threadPools = Executors.newFixedThreadPool(3);

    static class ListViewItem {
        public ImageView imageView;
    }

    public GoogleCardsAdapter(Context context) {
        this.mContext = context;
        this.mImagesLoader = ImagesLoader.getInstance();
    }

    @Override
    public int getCount() {
        return AppHelper.imagesId.length;
    }

    @Override
    public Object getItem(int position) {
        return AppHelper.imagesId[position];
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ListViewItem lvItem;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.listview_item, parent, false);
            lvItem = new ListViewItem();
            lvItem.imageView = (ImageView) convertView.findViewById(R.id.image);
            convertView.setTag(lvItem);
        } else {
            lvItem = (ListViewItem) convertView.getTag();
        }
        setImages(lvItem, position);
        lvItem.imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AppHelper.showPhotos(mContext,position);
            }
        });
        return convertView;
    }

    private void setImages(final ListViewItem lvItem, int position) {
        final int imageId = AppHelper.imagesId[position];
        final Handler myHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                Bitmap bp = (Bitmap) msg.obj;
                lvItem.imageView.setImageBitmap(bp);
            }

        };
        Bitmap bitmap = mImagesLoader.getBitmapFromMemCache(imageId);
        if (bitmap == null) {
            threadPools.submit(new Runnable() {
                @Override
                public void run() {
                    Bitmap bitmap = mImagesLoader.decodeSampleBitmapFromResource(mContext.getResources(), imageId, 600, 400);
                    Message msg = new Message();
                    msg.obj = bitmap;
                    msg.what = 1;
                    myHandler.sendMessage(msg);
                }
            });
        } else {
            lvItem.imageView.setImageBitmap(bitmap);
        }
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值