Android图⽚加载利器之Picasso基本⽤法
今天开始我们来学习⼀下Picasso,计划包括以下⼏⽅⾯的内容:
⽬前市场上⽐较流⾏的图⽚加载框架主要有UniversalImageLoader,Picasso,Glide,Fresco。
下⾯简单介绍⼀下这⼏个框架:
UniversalImageLoader:这个可以说是⾮常⾮常经典的⼀个了,相信每个app的开发⼈员都使⽤过,只可惜作者已经停⽌该项⽬的维护了,所以不太推荐使⽤。
Picasso:是Square公司出品的图⽚加载框架,Square出品必出精品,主要特点就是使⽤简单,扩展性强,⽀持各种来源的图⽚,包括⽹络、Resources、assets、files、content providers等。内部集成了OkHttp的⽹络框架,所以如果你的项⽬中使⽤了Square公司的其他框架,那么推荐使⽤Picasso,兼容性会好⼀些。⽬前在Github上的Star已经达到12758个。
Glide:是Google员⼯的开源项⽬,基于Picasso的⼀个框架,代码风格与Picasso⾮常相似,增加了更多的功能,⾮常重要的就是⽀持gif,当然它的包会⼤⼀些。如果你的项⽬对图⽚的使⽤场景⾮常多,并且需要⽀持gif,则推荐使⽤。⽬前在Github 上的Star已经达到13636个。
Fresco:是FB出品的开源框架,⽐较新,最⼤的优点就是在内存占⽤上的优化,极⼤的减少了OOM,功能上也包含了以上三种框架的功能,但是也带来了⼀个⽐较明显的缺点就是太⼤了,所以推荐使⽤在完全是做图⽚相关的app上,否则Picasso和Glide就完全够⽤了。⽬前在Github上的Star已经达到11983个。
上⾯主要对各种框架做个简单的介绍,既然是讲解Picasso的,那么接下来看看Picasso都有哪些功能。
1 提供内存和磁盘缓存,默认开启,可以设置不进⾏缓存
2 图⽚加载过程中默认显⽰的图⽚
3 图⽚加载失败或出错后显⽰的图⽚
4 图⽚加载成功或失败的回调
5 ⾃定义图⽚⼤⼩、⾃动测量ImageView⼤⼩、裁剪、旋转图⽚等
6 对图⽚进⾏转换
7 标签管理,暂停和恢复图⽚加载
8 请求优先级管理
9 可以从不同来源加载图⽚,⽹络、Resources、assets、files、content providers
10 更加丰富的扩展功能
以上这些功能将会在下⾯的⽂章中进⾏详细讲解。
上⾯我们提到了Picasso的诸多功能,下⾯我们来分别演⽰⼀下这些功能
配置:
在adle中添加引⽤
dependencies {
当当 电子书...
compile 'com.squareup.picasso:picasso:2.5.2'
...
}
1 加载图⽚
通过源码可以发现load⽅法主要要以下⼏种重载
load(Uri uri)
load(String path)
load(File file)
load(int resourceId)
//定义⼀张⽹络图⽚的uri,其实就是上⾯的测试图⽚
private static final String imageUrl = "imageMogr2/auto-orient/strip%7CimageView2/2/w/1240";
ImageView imageView = (ImageView) findViewById(R.id.imageView);
//从⽹络加载图⽚
Picasso.with(this).load(Uri.parse(imageUrl)).into(imageView);
Picasso.with(this).load(imageUrl).into(imageView);
//从res资源⽂件中加载图⽚
截图快捷键是什么Picasso.with(this).load(R.mipmap.default_image).into(imageView);
超级简单有⽊有,这⾥⾯只演⽰了两种⽅式。福特的车怎么样
牌牌琦被禁2 加载过程中显⽰默认图⽚placeholder
Picasso.with(this).load(imageUrl).placeholder(R.mipmap.default_image).into(imageView);
⼀般⽹络加载图⽚耗时⽐较长,所以会先默认显⽰⼀张替代的图⽚,只⽀持resId和Drawable本地图⽚。
3 加载失败后显⽰错误的图⽚
Picasso.with(this).load(imageUrl+"landptf").error(R.mipmap.default_image).into(imageView);
为了显⽰错误图⽚,这⾥⾯我在正确的地址后⾯拼了字符串构造了⼀个错误的地址,同样只⽀持本地的图⽚
崔雪梨4 图⽚填充⽅式
4.1 fit()
Picasso.with(this).load(imageUrl).fit().into(imageView);
该属性会根据Image View的⼤⼩充满整个View,不考虑⽐例,可能造成图⽚的拉伸或者缩⼩
4.2 centerCrop()
Picasso.with(this).load(imageUrl).resize(320, 640).centerCrop().into(imageView);
按⽐例裁减图⽚,使其居中显⽰,充满View,会造成图⽚显⽰不全,必须与resize⽅法同时使⽤
4.3 centerInside()
Picasso.with(this).load(imageUrl).resize(320, 640).centerInside().into(imageView);
按⽐例裁减图⽚,图⽚可以完全显⽰,但如果图⽚⽐View⼩,则⽆法充满整个View,必须与resize⽅法同时使⽤
4.4 onlyScaleDown()
Picasso.with(this).load(imageUrl).resize(1240, 1563).onlyScaleDown().into(imageView);
这⾥⾯使⽤的测试图⽚的⼤⼩是1240*1563,如果resize的宽⾼⼤于图⽚的原始宽⾼,则resize不起作⽤,采⽤图⽚原始宽⾼显⽰。
5 取消图⽚的过渡显⽰效果noFade()
Picasso.with(this).load(imageUrl).noFade().into(imageView);
默认情况下图⽚显⽰出来都会有⼀个过渡的效果,添加.noFade⽅法后,可以使该取消该效果,基本上很少使⽤
6 图⽚旋转rotate()
//以(0,0)为中⼼顺时针旋转45度
Picasso.with(this).load(imageUrl).rotate(45).into(imageView);
//以(64,64)为中⼼顺时针旋转45度
Picasso.with(this).load(imageUrl).rotate(45, 64, 64).into(imageView);
7 缓存策略
Picasso提供缓存的调试⽅法,通过如下代码可设置
Picasso.with(this).setIndicatorsEnabled(true);
效果图如下
卢婧珊可以看到图⽚的左上⾓有个蓝⾊的三⾓形,表⽰该图⽚是从磁盘加载的,另外如果为红⾊则表⽰从⽹络加载,如果为绿⾊表⽰
从内存加载。
Picasso的缓存流程是先检查内存是否有保存该图⽚,如果没有则检查磁盘是否有保存该图⽚,如果没有则从⽹络下载,下载成功之后分别保存到内存和磁盘上各⼀份,如果我们有时候不想缓存该图⽚或
者不想从缓存获取图⽚,该如何呢?Picasso也给我买提供了相应的控制⽅法。
Picasso.with(this)
.load(imageUrl)
.skipMemoryCache()
.into(imageView);
Picasso.with(this)
.load(imageUrl)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.into(imageView);
上⾯两个⽅法完全等价,但是第⼀种写法官⽅已经不推荐使⽤了,这⾥⾯列出来只是让⼤家了解⼀下。
这个表⽰什么意思呢?跳过从内存加载图⽚,并且图⽚下载之后也不在内存中进⾏缓存。
也就是图⽚的左上⾓的标识永远不可能为绿⾊。
MemoryPolicy.NO_CACHE:直接跳过检查内存是否有缓存该图⽚
MemoryPolicy.NO_STORE:图⽚下载之后不在内存中进⾏缓存
Picasso.with(this)
.load(imageUrl)
workPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
.into(imageView);
同理该⽅法表⽰跳过从磁盘加载图⽚,并且图⽚下载之后也不在磁盘中进⾏缓存。
这⾥注意只是不在磁盘中缓存,但是会在内存中缓存,因此若内存和磁盘中都不想缓存则需要和两个⽅法共同使⽤,如下:Picasso.with(this)
.load(imageUrl)
workPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.into(imageView);
NetworkPolicy枚举中还有⼀个值OFFLINE,这个表⽰强制从缓存中取,不会发起⽹络请求,如果缓存中没有也不会从⽹络中请求。
8 优先级priority
设想⼀种场景,当我们打开⼀个界⾯的时候,界⾯上有列表,每个列表项都有图⽚需要加载,列表上⾯还有⼀张图⽚需要提前加载,那么怎样来调度每个请求的优先级呢?
Picasso给我们提供了priority⽅法来管理请求的优先级
public enum Priority {
LOW,
NORMAL,
HIGH
}
通过priority⽅法的注释中可以知道默认的优先级是NORMAL,因此我们可以如下实现⾼优先级加载:
Picasso.with(this)
.load(imageUrl)
.priority(Picasso.Priority.HIGH)
.into(imageView);
9 tag标签管理
使⽤过list加载图⽚的童鞋都知道在列表滚动过程中停⽌加载图⽚,停⽌滚动时恢复图⽚加载,那么这样的功能在Picasso中时如何实现的呢?
这就⽤到了tag标签的功能
通过如下代码设置tag:
Picasso.with(this).load(imageUrl).tag("landptf").into(imageView);
在Picasso类中提供了如下⼏个⽅法来控制tag
cancelTag(Object tag)
pauseTag(Object tag)
resumeTag(Object tag)
通过名字可以很好理解了,我们在列表滚动的时候调⽤
Picasso.with(this).pauseTag("landptf");
在停⽌滚动的时候调⽤
Picasso.with(this).resumeTag("landptf");
⾄于cancelTag⽤于取消下载,⼀般我们在Activity销毁的时候将未完成的请求取消。
Picasso.with(this).cancelTag("landptf");
10 ⼿动指定key值stableKey
Picasso.with(this).load(imageUrl).stableKey("landptf").into(imageView);
我们猜想⼀个问题,Picasso是如何知道是否有缓存图⽚的,⼀般根据key值来判断,那么这个key值⼜是如何⽣成的呢?通过阅读源码可以知道,根据传⼊的uri或者resourceId,是否设置了旋转⾓度,是否设置了resize,或者是centerCrop还是centerInside等拼接出来的字符串,这⾥⾯我们可以通过stableKey⽅法来替换传⼊的uri或者resourceId⽣成key值。
好了,这篇⽂章就讲到这⾥了,在下⼀篇⽂章中我们将会继续学习Picasso的更⾼级的⽤法,通过扩展实现更加丰富的功能。