volley+listView结合使用时出现的问题以及解决方案

1.volley的介绍

volley的介绍就不用多说了,网上一搜一大堆,volley是一个综合性的开源框架,集请求网络,图片加载功能于一身,特别适合数据量小,通信频繁的操作,本篇文章主要涉及volley在加载图片方面的问题,至于velloy在其他方面的用法,感兴趣的读者可以在网络上查找资料学习

2.使用velloy加载网络图片

目前最火的加载图片的框架的莫过于UIL(Universal-Image-Loader)了,Volley是将AsyncHttpClient和Universal-Image-Loader的优点集成于一身的一个框架,个人觉得volley在加载大量图片的时候比UIL出色,接下来简答谈一下velloy从网络加载图片的用法

1.ImageRequest的用法

imageRequest大致可分为三步:创建RequestQueue对象,创建一个ImageRequest对象,将ImageRequest对象添加到RequestQueue里面

1.创建RequestQueue对象

//1.创建一个RequestQueue对象
    RequestQueue mRequestQueue= Volley.newRequestQueue(context);
2.创建一个ImageRequest对象

 //2.创建一个Request对象
    ImageRequest imageRequest=new ImageRequest("", new Response.Listener<Bitmap>() {
        @Override
        public void onResponse(Bitmap bitmap) {

        }
    }, 0, 0, Bitmap.Config.RGB_565, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {

        }
    });
很简单是不是,直接new就可以了,可以看到需要六个参数,第一个就是url地址,第二个是请求成功的回调,这里把返回的Bitmap参数设置到ImageView中,第六个参数则就是请求失败的回调了,可以在这里设置显示一张默认的图片,第三个和第四个参数表示允许图片的最大宽度和高度,默认都为0,如果指定图片的高度或宽度大于这个值,则会对图片进行压缩,指定为0 表示不管多大都不会进行压缩,第五个参数用于表示颜色属性

3.将ImageRequest对象添加到RequestQueue中

//3.将ImageRequest对象添加到RequestQueue中
    mRequestQueue.add(imageRequest);
这是ImageRequest的用法,接下来我们谈谈更加好用的ImageLoader的用法

2.ImageLoader的用法

imageLoader比起ImageRequest更加的高效,笔者在项目中也是用这种方法加载网络图片,ImageLoader不仅可以帮我们进行图片缓存,还可以避免重复请求

ImageLoader的用法大致可以分为四步:第一步和ImageRequest一样也是创建一个RequestQueue对象,第二步为创建一个ImageLoader对象,第三步为获取一个ImageListener对象,第四步ImageLoader的get方法加载网络上的图片

1.创建一个RquestQueue对象,与ImageRequest用法一样,就不再叙述

2.创建一个ImageLoader对象

 //2.创建一个ImageLoader对象
    ImageLoader imageLoader=new ImageLoader(mRequestQueue, new ImageLoader.ImageCache() {
       @Override
       public Bitmap getBitmap(String s) {
           return null;
       }

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

       }
   });
可以看到接收两个参数,一个是RequestQueue对象,一个是ImageCache,这里先new一个空的实现

3.获取一个ImageListener对象

//3.获取一个ImageListener
    ImageLoader.ImageListener listener=ImageLoader.getImageListener(imageView, R.mipmap.bar_brand_normal,R.mipmap.bar);
第一个参数为ImageVIew对象,第二个参数为默认显示的图片,第三个为加载失败显示的图片

4.ImageLoader的get方法显示图片

//4.ImageLoader的get方法显示图片
        imageLoader.get("",listener);
很简单明了,第一个参数是url地址,第二个则是我们上一步的listener对象

IamgeLoader的用法就是这么简单的几步了,但是还没有完,我们在第二步时候new了一个ImageCache的空实现,完全没有起到缓存的作用,其实写一个缓存也非常简单,借助于lruCache就可以了。我们新建一个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,这样就简单的实现了缓存,在把第二步的空实现改为我们自己的BitmapCache就可以了
以上就是ImageLoader的使用方法,接下来笔者将要讲的是在工作中使用ImageLoader异步加载listView中的图片时候碰到的问题

相信很多人在listView中加载图片,快速滑动时候都出现过图片错位,乱跳的情况,笔者也不例外,虽然用ImageLoader解决了异步加载图片的问题,也不会出现oom,但是图片跳动错位的问题却没有解决,网上很多人提供的方法都是给ImageView设置一个tag,然后在加载完成时判断当前IamgeView的tag是否一致,如果一致则显示,否则不予显示,但是笔者发现在用ImageLoader时这样做并卵,因为图片的加载和显示都是在get方法里面就完成了,这样设置tag的方法就不起作用了,为了解决这个问题,可费了不少功夫,其实后来发现如果不用ImageLoader就可以解决问题,后面会讲到volley的另一种加载网络图片的方法,就不会出现这种问题,但是笔者又不想放弃ImageLoader这么优秀的方法,如果能解决就最好了,果然皇天不负有心人,在ImageLoader内部有一个getImageListener方法,该方法接收了三个参数,和前面我们在得到ImageListener需要的参数一模一样,原来我们的listener就是通过这个方法得来的,就是这个方法解决了图片错乱问题,他的重写方法,接收了四个参数

 /**
     * 使用此方法能够解决图片错乱问题
     * @param view
     * @param defaultImageResId
     * @param errorImageResId
     * @param url
     * @return
     */
    public static com.android.volley.toolbox.ImageLoader.ImageListener getImageListener(
            final ImageView view,
            final int defaultImageResId,
            final int errorImageResId,
            final String url) {
        return new com.android.volley.toolbox.ImageLoader.ImageListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                if (errorImageResId != 0) {
                    view.setImageResource(errorImageResId);
                }
            }

            @Override
            public void onResponse(com.android.volley.toolbox.ImageLoader.ImageContainer response, boolean isImmediate) {
                if (response.getBitmap() != null) {
                    //在这里可以设置,如果想得到圆角图片的画,可以对bitmap进行加工,可以给imageview加一个
                    //额外的参数
                    String urlTag = (String) view.getTag();
                    if(urlTag!=null && urlTag.trim().equals(url)){
                        view.setImageBitmap(response.getBitmap());
                    }
                } else if (defaultImageResId != 0) {
                    view.setImageResource(defaultImageResId);
                }
            }
        };
    }
我们在得到listener的时候通过我们重写的这个方法去得到,就可以完美的解决图片错乱的问题

最后再谈谈volley最后一种加载网络图片的方法,即NetWorkImageView

NetworkImageView控件的用法要比前几种方式更加简单,大致可以分为以下五步:

1. 创建一个RequestQueue对象。

2. 创建一个ImageLoader对象。

3. 在布局文件中添加一个NetworkImageView控件。

4. 在代码中获取该控件的实例。

5. 设置要加载的图片地址。

第一步和第二步就不多说了,和前面是一样的,第三步要稍微注意,这里我们用的控件不是ImageView了而是NetWorkImageView

在第四步得到了NetworkImageView控件的实例之后,我们可以调用它的setDefaultImageResId()方法、setErrorImageResId()方法和setImageUrl()方法来分别设置加载中显示的图片,加载失败时显示的图片,以及目标图片的URL地址

networkImageView.setDefaultImageResId(R.mipmap.bar_brand_normal);  
networkImageView.setErrorImageResId(R.mipmap.bar_brand_normal<span style="font-family: Arial;">);  </span>
networkImageView.setImageUrl("",imageLoader);  
接收两个参数,和前面的都一样的,第一个为url地址,第二个为ImageLoader对象
是不是很简单,而且笔者亲测不会产生图片跳动错乱的问题,有兴趣的朋友可以用这种方法试试看
好了,关于volley的一些心得就先分享到这里了




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值