picasso教程

1.背景:picasso是Square公司出的一款图片加载框架,能够解决我们在Android开发中加载图片时遇到的诸多问题,比如OOM,图片错位等,问题主要集中在加载图片列表时,因为单张图片加载谁都会写。如果我们想在ListView或者GridView或者RecyclerView中加载图片墙,那么这个时候对原图片的二次处理就显得非常重要了,否则就会出现我们上文说的OOM或者图片错位等。不过,如果你使用了Picasso来加载图片的话,那么所有问题都会变得很简单

1.加载网络图片:
Picasso.with(this).load(“http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg“).into(iv);
2.对网络图片裁剪:
Picasso.with(this).load(“http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg“)
.resize(200,200)
.into(iv);
注意这里的200表示200px,如果你想在resize时指定dp,可以使用如下方法:
Picasso.with(this).load(“http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg“)
.resizeDimen(R.dimen.iv_width,R.dimen.iv_height)
.into(iv);
Picasso.with(this).load(“http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg“)
.resizeDimen(R.dimen.iv_width,R.dimen.iv_height)
.centerCrop()
.into(iv);
很多时候我还可以给Picasso下载的图片设置缩放模式,也就是ImageView的ScaleType属性,
但是注意,缩放模式centerCrop和centerInside要和resize一起使用,否则会抛异常,而缩放模式fit不可以和resize一起使用,如下:

Picasso.with(this).load(“http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg“)
//占位图,图片加载出来之前显示的默认图片
.placeholder(R.mipmap.ic_launcher)
//错误图,图片加载出错时显示的图片
.error(R.mipmap.ic_launcher)
.into(iv);
很多时候我们在图片加载出来之前需要先显示一张默认图片,也即占位图,而在图片加载出错的时候我们可能想显示一张错误图,这个Picasso也是支持的
Picasso.with(this).load(“http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg“)
.transform(transformation)
.into(iv);

查看图片从哪里加载
Picasso picasso = Picasso.with(this);
//开启指示器
picasso.setIndicatorsEnabled(true);
picasso.load(“http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg“)
.into(iv);
缓存
默认缓存位置:data/data/packagename/cache
缓存方式:Disk 和 Memory
缓存策略:
NO_CACHE:表示处理请求的时候跳过检查内存缓存
NO_STORE: 表示请求成功之后,不将最终的结果存到内存

with(this).load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) //禁止内存缓存
.into(mBlurImage);

现在大部分的图片缓存框架都是支持三级缓存的,在Picasso中,我们也可以手动设置缓存策略,比如说当我们查看一张大图的时候,
可能由于图片太大,不想将其缓存在内存中,那么可以自定义缓存策略, data/data/packagename/.如果我们使用with来构建Picasso 的实例的话,
Picasso会通过Builder模式为我们初始化一个默认的下载器:而Picasso创建的下载器会优先使用OkHttp,如果项目没有添加OkHttp依赖的话会使用
HttpUrlConnection,检查是否添加依赖使用了反射来检查:,默认情况下,Picasso 内存缓存和磁盘缓存都开启了的,也就是加载图片的时候,内存和磁盘都缓存了,但是有些时候,我们并不需要缓存,比如说:加载一张大图片的时候,
如果再内存中保存一份,很容易造成OOM,这时候我们只希望有磁盘缓存,而不希望缓存到内存,因此就需要我们设置缓存策略了。Picasso 提供了这样的方法。

磁盘缓存:
NO_CACHE: 表示处理请求的时候跳过处理磁盘缓存
NO_STORE: 表示请求成功后,不将结果缓存到Disk,但是这个只对OkHttp有效。
OFFLINE: 这个就跟 上面两个不一样了,如果networkPolicy方法用的是这个参数,那么
Picasso会强制这次请求从缓存中获取结果,不会发起网络请求,不管缓存中能否获取到结果。

with(this).load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)//跳过内存缓存
.networkPolicy(NetworkPolicy.NO_CACHE)//跳过磁盘缓存
.into(mBlurImage);

强制从缓存获取:
with(this).load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.networkPolicy(NetworkPolicy.OFFLINE)//强制从缓存获取结果
.into(mBlurImage);

默认缓存位置:

static Downloader createDefaultDownloader(Context context) {
try {
Class.forName(“com.squareup.okhttp.OkHttpClient”);
return OkHttpLoaderCreator.create(context);
} catch (ClassNotFoundException ignored) {
}
return new UrlConnectionDownloader(context);
}

扫描二维码关注公众号,回复: 1173435 查看本文章

这里就很明白了,系统通过反射来检查我们在项目中是否使用了OkHttp,如果使用了,就使用OkHttp来创建一个下载器,否则就使用HttpUrlConnection来创建一个下载器,可是大家注意Class.forName(“com.squareup.okhttp.OkHttpClient”);这个方法的参数,这是OkHttp3以前的写法,现在我们都是使用OkHttp3了,OkHttp3的包名就不是这个样子,而是okhttp3.OkHttpClient,所以即使你在项目中引用了OkHttp3,Picasso还是会把HttpUrlConnection当作下载器来下载图片的,这个问题估计Picasso会在以后的版本中修正吧!

自定义下载器:

Picasso picasso = new Picasso.Builder(this)
.downloader(new OkHttp3Downloader(this.getExternalCacheDir()))
.build();
Picasso.setSingletonInstance(picasso);
picasso.load(“http://n.sinaimg.cn/translate/20160819/9BpA-fxvcsrn8627957.jpg“).into(iv);

其实很简单,首先不使用with这个方法来初始化Picasso,而是使用Builder来初始化,在初始化的过程中传入自己的下载器,这个下载器需要自己写,
自己的下载器我们可以模仿Picasso里边的这个下载器来写,也可以自定义,我们来看一个Demo:

Tag管理请求:

cancelTag(Object tag) 取消设置了给定tag的所有请求
pauseTag(Object tag) 暂停设置了给定tag 的所有请求
resumeTag(Object tag) resume 被暂停的给定tag的所有请求

Adapter中添加如下代码:
Picasso.with(this).load(mData.get(position))
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.tag(“PhotoTag”)
.into(holder.mImageView);

使用场景:
比如一个照片流列表,当我们快速滑动列表浏览照片的时候,后台会一直发起请求加载照片的,这可能会导致卡顿,那么我们就可以为
每个请求设置一个相同的Tag,在快速滑动的时候,调用pauseTag暂停请求,当滑动停止的时候,调用resumeTag恢复请求,这样的
体验是不是就会更好一些呢。

Activity中为RecyclerView添加滑动监听

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
final Picasso picasso = Picasso.with(MainActivity.this);

            if (newState == SCROLL_STATE_IDLE) {
                picasso.resumeTag("PhotoTag");
            } else {
                picasso.pauseTag("PhotoTag");
            }
        }
    });

线程池:

PicassoExecutorService:默认3个线程

也可以自定义线程池

猜你喜欢

转载自blog.csdn.net/qq_18757557/article/details/78831374