ImageRequest、ImageLoader、NewworkImageView都是Volley框架中用于请求网络图片的,当我们请求图片时,必须要考虑的就是缓存的设置,如何把 第一次请求下来的图片放到缓存中,从而在第二次打开APP或者在没有网络的情况下,不需要请求网络而直接在缓存中引用,这样节省了用户流量,同时也会有好的用户体验。
一。ImageRequest
ImageRequest和之前的StringRequest和JsonRequest步骤完全一样;
第一步:得到请求队列对象
requestQueue = Volley.newRequestQueue(this);
第二步:得到请求对象,分别实现两个接口,请求成功的和失败的,并实现各自方法
imageRequest=new ImageRequest(path,this,this);
第三步:把请求对象加入到请求队列中
requestQueue.add(imageRequest);
第四步:设置取消请求
imageRequest.setTag(TAG);
requestQueue.cancelAll(TAG);
这种方式可不推荐,因为没有设置缓存,所以在请求网络图片时,几乎不用这种方式,而是用后两种。
二.ImageLoader
第一步:创建ImageLoader对象
ImageLoader loader=new ImageLoader(queue,this);
第一个参数是RequestQueue,第二个参数是一个接口,实现它的两个方法:getBitmap()和putBitmap();
第二步:轮到缓存登场了,用LruCache(最近最少使用算法)缓存,当LruCache中的数据满时,把最近最不常使用的清除掉;要注意的是,1.缓存对象必须是静态的。2.LruCache存在于两个包中,一个是android.utils包中的,一个是V4包中的,前者API低于12时不兼容,推荐选后者。
private static LruCache<String,Bitmap> cache=new LruCache<String,Bitmap>((int) (Runtime.getRuntime().totalMemory()/4)){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight();
}
};
参数:设置内存大小,这里表示运行时全部内存的1/4;
方法:用来测量方法cache中的元素内存大小,返回上述返回值即可;
第三步:存放和读取:
存放时:
public Bitmap getBitmap(String url) {
return cache.get(url);
}
读取时:
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url,bitmap);
}
第四步:请求网络:
loader.get(url,ImageLoader.getImageListener(viewHolder.imageView,R.mipmap.ic_launcher,R.mipmap.ic_launcher));
1参:请求图片路径
2参中的1参:下载的图片存放位置,2参:默认显示的图片;3参:下载失败时显示的图片
实例代码如下:
public class TeaAdapter extends BaseAdapter implements ImageLoader.ImageCache {
private Context context;
private List<Tea> list;
private RequestQueue requestQueue;
private ImageLoader loader;
private RoundRect rect;
private static LruCache<String,Bitmap> cache=new LruCache<String,Bitmap>((int) (Runtime.getRuntime().totalMemory()/4)){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight();
}
};
public TeaAdapter(Context context, List<Tea> list) {
this.context = context;
this.list = list;
requestQueue = Volley.newRequestQueue(context);
loader=new ImageLoader(requestQueue,this);
rect=new RoundRect();
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
convertView= LayoutInflater.from(context).inflate(R.layout.item_layout,null);
ViewHolder viewHolder=new ViewHolder();
viewHolder.imageView= (NetworkImageView) convertView.findViewById(R.id.imageView);
viewHolder.textView_nickname= (TextView) convertView.findViewById(R.id.textView_nick);
viewHolder.textView_source= (TextView) convertView.findViewById(R.id.textView_source);
viewHolder.textView_title= (TextView) convertView.findViewById(R.id.textView_title);
convertView.setTag(viewHolder);
}
ViewHolder viewHolder= (ViewHolder) convertView.getTag();
viewHolder.textView_title.setText(list.get(position).getTitle());
viewHolder.textView_source.setText(list.get(position).getSource());
viewHolder.textView_nickname.setText(list.get(position).getNickname());
String url=list.get(position).getWb_thumb();
if(!TextUtils.isEmpty(url)){
loader.get(url,ImageLoader.getImageListener(viewHolder.imageView,R.mipmap.ic_launcher,R.mipmap.ic_launcher));
}
return convertView;
}
//存放时
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
//读取时
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url,bitmap);
}
public static class ViewHolder{
NetworkImageView imageView;
TextView textView_title,textView_source,textView_nickname;
}
}
三.NewWorkImageView
用NewWorkImageView时,我们只需要把布局文件中的ImageView 改为com.android.volley.toolbox.NetworkImageView。
<com.android.volley.toolbox.NetworkImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:src="@mipmap/ic_launcher"/>
在请求时:
viewHolder.imageView.setImageUrl(url,loader);