本博客多處參考了郭霖大神的博客http://blog.csdn.net/guolin_blog/article/details/9316683,十分感謝他的無私分享
ImageLoader的使用
- ImageLoader也可以用於加載網絡上的圖片,並且它的內部也是使用ImageRequest來實現的,不過ImageLoader明顯要比ImageRequest更加高效,因爲它不僅可以幫我們對圖片進行緩存,還可以過濾掉重複的鏈接,避免重複發送請求。
由於ImageLoader已經不是繼承自Request的了,所以它的用法也和我們之前學到的內容有所不同,總結起來大致可以分爲以下四步:
- 創建一個RequestQueue對象。
- 創建一個ImageLoader對象。
- 獲取一個ImageListener對象。
- 調用ImageLoader的get()方法加載網絡上的圖片。
public class VolleyUtils {
private static VolleyUtils volleyUtils;
private static RequestQueue requestQueue;//消息隊列
private ImageLoader imageLoader;//ImageLoader對象
private Context context;
private VolleyUtils(Context context) {
this.context=context;
requestQueue= Volley.newRequestQueue(context);
}
public static synchronized VolleyUtils newInstance(Context context){
if (requestQueue==null){
volleyUtils=new VolleyUtils(context);
}
return volleyUtils;
}
public RequestQueue getRequestQueue(){
if(requestQueue == null){
requestQueue = Volley.newRequestQueue(context.getApplicationContext());
}
return requestQueue;
}
//ImageLoader的構造函數接收兩個參數,第一個參數就是RequestQueue對象,第二個參數是一個ImageCache對象,這裏我們先new出一個空的ImageCache的實現即可。
public ImageLoader getImageLoader() {
imageLoader=new ImageLoader(getRequestQueue(), new ImageLoader.ImageCache() {
@Override
public Bitmap getBitmap(String url) {
return null;
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
}
});
return imageLoader;
}
public void addRequestQueue(Request request){
getRequestQueue().add(request);
}
}
ImageLoader的構造函數接收兩個參數,第一個參數就是RequestQueue對象,第二個參數是一個ImageCache對象,這裏我們先new出一個空的ImageCache的實現即可。
然後我們在對應的點擊事件中的邏輯如下
ImageLoader.ImageListener listener = ImageLoader.getImageListener(imageView, R.mipmap.default_image, R.mipmap.failed_image);
VolleyUtils.newInstance(getApplicationContext()).getImageLoader().get("https://img-my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", listener);
我們通過調用ImageLoader的getImageListener()方法能夠獲取到一個ImageListener對象,getImageListener()方法接收三個參數,第一個參數指定用於顯示圖片的ImageView控件,第二個參數指定加載圖片的過程中顯示的圖片,第三個參數指定加載圖片失敗的情況下顯示的圖片。
最後,調用ImageLoader的get()方法來加載圖片如果想對圖片指定大小也可以這樣
VolleyUtils.newInstance(getApplicationContext()).getImageLoader().get("https://img-my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", listener,200,200);
應用圖片的緩存功能
這裏我們新建一個BitmapCache並實現了ImageCache接口,如下所示:
public class BitmapCache implements ImageCache {
private LruCache<String, Bitmap> mCache;
public BitmapCache() {
int maxSize = 10 * 1024 * 1024;
mCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return mCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
mCache.put(url, bitmap);
}
}
可以看到,這裏我們將緩存圖片的大小設置爲10M。接着修改創建ImageLoader實例的代碼,第二個參數傳入BitmapCache的實例,如下所示:
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
這樣我們就把ImageLoader的功能優勢充分利用起來了。
這一部分摘自郭霖大神的博客http://blog.csdn.net/guolin_blog/article/details/9316683
我自己的寫得代碼如下:
- 首先BitmapCache是一樣的,直接拷貝的
public class BitmapCache implements ImageLoader.ImageCache {
private LruCache<String, Bitmap> mCache;
public BitmapCache() {
int maxSize = 10 * 1024 * 1024;
mCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return mCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
mCache.put(url, bitmap);
}
}
- 再然後就是點擊事件的邏輯處理
ImageLoader.ImageListener listener = ImageLoader.getImageListener(imageView, R.mipmap.default_image, R.mipmap.failed_image);
//可以看出來,加了緩存功能就是這裏創建ImageLoader和上面不一樣了,這裏使用了我們光創建的緩存的工具類
ImageLoader imageLoader = new ImageLoader(VolleyUtils.newInstance(getApplicationContext()).getRequestQueue(), new BitmapCache());
imageLoader.get("https://img-my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", listener);
NetworkImageView的使用
- NetworkImageView是一個自定義控制,它是繼承自ImageView的,具備ImageView控件的所有功能,並且在原生的基礎之上加入了加載網絡圖片的功能。NetworkImageView控件的用法要比前兩種方式更加簡單,大致可以分爲以下五步:
- 創建一個RequestQueue對象。
- 創建一個ImageLoader對象。
- 在佈局文件中添加一個NetworkImageView控件。
- 在代碼中獲取該控件的實例。
- 設置要加載的圖片地址。
其中,第一第二步和ImageLoader的用法是完全一樣的,因此這裏我們就從第三步開始學習了。首先修改佈局文件中的代碼,在裏面加入NetworkImageView控件,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Request" />
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/network_image_view"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>
接着在Activity獲取到這個控件的實例,這就非常簡單了,代碼如下所示:
networkImageView = (NetworkImageView) findViewById(R.id.network_image_view);
得到了NetworkImageView控件的實例之後,我們可以調用它的setDefaultImageResId()方法、setErrorImageResId()方法和setImageUrl()方法來分別設置加載中顯示的圖片,加載失敗時顯示的圖片,以及目標圖片的URL地址,如下所示:
networkImageView.setDefaultImageResId(R.drawable.default_image);
networkImageView.setErrorImageResId(R.drawable.failed_image);
networkImageView.setImageUrl("https://img-my.csdn.net/uploads/201404/13/1397393290_5765.jpeg",
imageLoader);
- 其中,setImageUrl()方法接收兩個參數,第一個參數用於指定圖片的URL地址,第二個參數則是前面創建好的ImageLoader對象。
- 使用ImageRequest和ImageLoader這兩種方式來加載網絡圖片,都可以傳入一個最大寬度和高度的參數來對圖片進行壓縮,而NetworkImageView中則完全沒有提供設置最大寬度和高度的方法,那麼是不是使用NetworkImageView來加載的圖片都不會進行壓縮呢?
其實並不是這樣的,NetworkImageView並不需要提供任何設置最大寬高的方法也能夠對加載的圖片進行壓縮。這是由於NetworkImageView是一個控件,在加載圖片的時候它會自動獲取自身的寬高,然後對比網絡圖片的寬度,再決定是否需要對圖片進行壓縮。也就是說,壓縮過程是在內部完全自動化的,並不需要我們關心,NetworkImageView會始終呈現給我們一張大小剛剛好的網絡圖片,不會多佔用任何一點內存,這也是NetworkImageView最簡單好用的一點吧。
當然了,如果你不想對圖片進行壓縮的話,其實也很簡單,只需要在佈局文件中把NetworkImageView的layout_width和layout_height都設置成wrap_content就可以了,這樣NetworkImageView就會將該圖片的原始大小展示出來,不會進行任何壓縮。
另外一個image-loader的使用
首先需要我們導入包
然後的邏輯代碼很簡單如下:
ImageLoader imageLoader=ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(context));
imageLoader.displayImage(newsDetial.getImg(),viewHolder.imageView);
- 就可以講對應網絡上的圖片加載到imageView上了