在上一篇博客《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加載圖片的三種方式。當然,我們還可以把代碼進一步封裝以減少重複的工作。
下一篇《Volley框架(三):使用Volley提交表單數據》