Volley框架(二):使用Volley加载图片

在上一篇博客《Volley框架(一):使用Volley请求数据》中我们知道了使用Volley请求网络数据并封装成我们自定义的格式,今天我们就来看一下Volley的另外一个作用,使用Volley加载图片,同时使用Volley还能非常简单的实现内存和磁盘缓存,达到类似Universal-Image-Loader图片加载框架的功能。

 

使用Volley加载图片有三种方式:
1、使用ImageRequest

2、使用Volley提供的ImageLoader加载图片

3、使用Volley定义的控件NetworkImageView

 

1、使用ImageRequest
看到ImageRequest这个名字,我们就应该能联想到上一篇文章中说到的Volley请求数据的方式,ImageRequest和StringRequest、JsonRequest类似;事实也是如此,ImageRequest的使用方式和他们也是一样,分为三步。

 

private void loadImage() {
	// 1.创建RequestQueue队列
	RequestQueue requestQueue = Volley.newRequestQueue(this);
	// 2.创建ImageRequest请求
	String imgUrl = "http://p.3761.com/pic/72671370486910.jpg";
	ImageRequest imageRequest = new ImageRequest(imgUrl, new Response.Listener<Bitmap>() {
		@Override
		public void onResponse(Bitmap response) {
			imageView.setImageBitmap(response);
		}
	}, 400, 400, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {
		@Override
		public void onErrorResponse(VolleyError error) {
			imageView.setBackgroundResource(R.mipmap.default_img);
		}
	});
	// 3.将ImageRequest添加到RequestQueue
	requestQueue.add(imageRequest);
}

 

运行结果:

ImageRequest只有一个构造方法,需要6个参数:
第一个参数:需要加载图片的地址
第二个参数:加载完成时的监听,将加载的图片设置到ImageView控件当中
第三、四个参数:这个两个参数表示需要加载的图片的宽和高,如果网络图片大于设置的宽和高Volley就会对图片进行压缩,如果设置为0表示加载完整图片
第五个参数:指定图片的颜色属性,主要有ALPHA_8,RGB_565, ARGB_4444, ARGB_8888几种
第六个参数:加载失败时的监听,上面的代码是为ImageView设置了一个默认图片

 

 

2、使用Volley提供的ImageLoader加载图片
在上面我们使用Volley的ImageRequest实现了图片的加载,但是还是感觉缺少点什么。没错,就是没有对图片进行缓存和过滤掉重复的请求,所以Volley提供了一个ImageLoader来加载图片,虽然它内部也是使用的ImageRequest,但是它更加高效,而且实现的缓存和过滤重复的请求。使用Volley的ImageLoader一般分为以下几个步骤。
① 创建一个RequestQueue对象。
② 创建一个ImageLoader对象。
③ 获取一个ImageListener对象。
④ 调用ImageLoader的get()方法加载网络上的图片。

 

 

 

private void imageLoaderLoad() {
	String imgUrl = "http://p.3761.com/pic/72671370486910.jpg";
	// 1.创建RequestQueue队列
	RequestQueue requestQueue = Volley.newRequestQueue(this);
	// 2.创建ImageLoader对象,需要两个参数 RequestQueue对象和 ImageCache对象,在这里先使用空实现
	ImageLoader imageLoader = new ImageLoader(requestQueue, new ImageLoader.ImageCache() {
		@Override
		public Bitmap getBitmap(String url) {
			return null;
		}

		@Override
		public void putBitmap(String url, Bitmap bitmap) {

		}
	});
	// 3.通过ImageLoader的静态方法获取ImageListener对象,可以指定加载时显示的图片和加载失败时显示的图片
	ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(imageView, R.mipmap.default_img, R.mipmap.error_img);
	// 4.将图片地址和 ImageListener对象作为参数,使用ImageLoader的get()方法加载图片
	imageLoader.get(imgUrl,imageListener);
	// 重载方法,指定需要加载图片的大小
	// imageLoader.get(imgUrl,imageListener,400,400);
}

结果也能加载出图片,所以不再贴出结果了。

 

虽然实现了图片的加载,但是我们并没有过滤掉重复的请求和实现图片的缓存,因为在创建ImageLoader的时候,ImageCache对象我们使用的是空实现。下面我们就来实现一下ImageCache。

public class VImageCache implements ImageLoader.ImageCache {
    // 使用Android提供的LruCache类
    private static LruCache<String, Bitmap> mVolleyImgCache;

    public VImageCache() {
        // 使用应用程序可用的最大内存的1/8作为缓存图片的内存缓存
        int volleyImgMaxMemory = (int) (Runtime.getRuntime().maxMemory() / 8);
        mVolleyImgCache = new LruCache<String, Bitmap>(volleyImgMaxMemory) {
            // 返回图片的大小,必须重写,否则返回0
            @Override
            protected int sizeOf(String key, Bitmap value) {
                // return value.getByteCount(); // 在Android版本为KITKAT(Android 4.4)以上才可以用
                return value.getRowBytes() * value.getHeight();
            }
        };
    }

    @Override
    public Bitmap getBitmap(String url) {
        return mVolleyImgCache.get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        mVolleyImgCache.put(url, bitmap);
    }
}

所以上面的代码就可以写成这样,使用新建的VImageCache类作为缓存类:

private void imageLoaderLoad() {
	String imgUrl = "http://p.3761.com/pic/72671370486910.jpg";
	// 1.创建RequestQueue队列
	RequestQueue requestQueue = Volley.newRequestQueue(this);
	// 2.创建ImageLoader对象,需要两个参数 RequestQueue对象和 ImageCache对象,在这里先使用空实现
	ImageLoader imageLoader = new ImageLoader(requestQueue, new VImageCache());
	// 3.通过ImageLoader的静态方法获取ImageListener对象
	ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(imageView, R.mipmap.default_img, R.mipmap.error_img);
	// 4.将图片地址和 ImageListener对象作为参数,使用ImageLoader的get()方法加载图片
	imageLoader.get(imgUrl,imageListener);
	// 重载方法,指定需要加载图片的大小
	// imageLoader.get(imgUrl,imageListener,400,400);
}ImageLoader imageLoader = new ImageLoader(requestQueue, new VImageCache());
	// 3.通过ImageLoader的静态方法获取ImageListener对象
	ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(imageView, R.mipmap.default_img, R.mipmap.error_img);
	// 4.将图片地址和 ImageListener对象作为参数,使用ImageLoader的get()方法加载图片
	imageLoader.get(imgUrl,imageListener);
	// 重载方法,指定需要加载图片的大小
	// imageLoader.get(imgUrl,imageListener,400,400);
}

这样我们就实现了请求的过滤和图片的缓存,需要注意的是Volley已经实现了磁盘缓存,所以并不需要我们手动的实现磁盘缓存。
 

 

3、使用Volley定义的控件NetworkImageView
Volley除了上面两种方式加载图片,还有一种就是使用Volley的自定义控件NetworkImageView,这个控件同样也能实现缓存和过滤请求,而且使用起来要更加的简单,主要可以分为以下几步:
① 在布局文件中添加一个NetworkImageView控件。
② 在代码中获取该控件的实例。
③ 创建一个RequestQueue对象。
④ 创建一个ImageLoader对象。
⑤ 设置要加载的图片地址。

在布局中定义

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.android.volley.toolbox.NetworkImageView
        android:id="@+id/net_image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

在Activity中获取控件

 

 

NetworkImageView netImageView = (NetworkImageView) findViewById(R.id.net_image_view);

 

加载图片

String imgUrl = "http://p.3761.com/pic/72671370486910.jpg";
// 设置默认图片
netImageView.setDefaultImageResId(R.mipmap.default_img);
// 设置加载失败时的图片
netImageView.setErrorImageResId(R.mipmap.error_img);
// 创建RequestQueue
RequestQueue requestQueue = Volley.newRequestQueue(this);
// 创建ImageLoader,使用刚刚创建的ImageCache类
ImageLoader imageLoader = new ImageLoader(requestQueue, new VImageCache());
// 设置加载路径和ImageLoader对象
netImageView.setImageUrl(imgUrl,imageLoader);


在NetworkImageView中就没有上面两种加载方式中指定大小的方法了,因为NetworkImageView本身就是一个控件,我们完全可以在布局文件中给他指定大小,在加载图片的时候Volley先读取布局文件中给控件指定的大小然后再从网络上加载相应大小的图片,如果需要加载原图,就把控件的宽和高都指定为wrap_content即可。

 

 

 

以上就是使用Volley加载图片的三种方式。当然,我们还可以把代码进一步封装以减少重复的工作。

 

CSDN下载GitHub下载

下一篇《Volley框架(三):使用Volley提交表单数据

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章