简介
Picasso
是Square
公司开源的一个Android
图形缓存库,可以实现图片下载和缓存功能。
主要有以下一些特性:
- 在
Adapter
中回收和取消已经不在视野范围图片资源的加载,防止可能出现的图片错位; - 使用复杂的图片压缩转换来尽可能的减少内存消耗;
- 使用最少的内存完成复杂的图形转换操作;
- 自带内存和硬盘缓存;
- 可加载网络或本地资源。
GitHub
地址:
背景
Android
系统作为图片资源加载的主角,它是通过图像的像素点来将图像加载到内存中的。现在一张500W
的摄像头拍出的照片(2592x1936)
加载到内存中需要大约19M
的内存,如果你加入了在信号强度不一的网络中进行复杂的网络请求,并进行图片的缓存与其他处理时,你将会耗费大量的时间与精力来处理这些问题,但如果使用Picasso
进行加载实现这些问题都将会得到很好的解决。
配置
build.gradle
配置:
compile 'com.squareup.picasso:picasso:2.5.2'
混淆配置:
-dontwarn com.squareup.okhttp.**
网络配置:
<uses-permission android:name="android.permission.INTERNET" />
图片加载
Picasso
使用简单易用的接口,并有一个实现类Picasso
,一个完整的图片加载请求至少需要三个参数:
with(Context context):
上下文;
load(String path):
加载图片的地址;
into(ImageView target):
图片展示的ImageView
。
简单用例:
Picasso.with(mActivity)
.load(Constant.picUrl)
.into(mIvNetworkPictures);
其他加载方式:
可以加载资源文件、本地File
文件、Uri
地址等。
常用方法
1. .noFade()
:
Picasso
的默认图片加载方式有一个淡入的效果,如果调用了noFade()
方法后加载的图片将直接显示在ImageView
上。
2. .noPlaceholder()
:
有一个场景,当你从网上加载了一张图片到Imageview
上后,过了一段时间想在同一个ImageView
上展示另外一张图片。这个时候你就会去调用Picasso
进行二次请求,这时Picasso
就会把之前的图片进行清除,可能展示的是.placeholder()
状态的图片,给用户并不是很好的体验,如果调用了noPlaceholder()
方法就不会出现这种情况了。
3. .resize(int targetWidth, int targetHeight)
:
如果图片很大或者想自定义图片的显示样式时,可以使用此方法来裁剪图片尺寸。
4. .onlyScaleDown()
:
如果调用了resize(width,height)
方法的话,Picasso
一般会重新计算以改变图片的加载质量,比如一张小图变成一张大图进行展示的时候。但是如果我们的原图是比重新resize
的新图规格大的时候,我们就可以调用onlyScaleDown()
来直接进行展示而不再重新计算,缩短图片的加载计算时间。
5. .centerInside()
:
图片会被完整的展示,可能图片不会填充满ImageView
,也有可能会被拉伸或者挤压,一般是等比例缩小。
6. .centerCrop()
:
图片会被裁剪,但是图片质量没有什么区别,等比例放大。
7. .fit()
:
Picasso
会对图片的大小及ImageView
进行测量,计算出最佳的大小及最佳的图片质量来进行图片展示,减少内存的消耗并对视图没有影响。
8. .priority()
:
如果一个视图中顶部图片较大而底部图片较小,因为Picasso
是异步加载,所以小图会先加载出来。但是对于用户来说或许更希望看到的是上面的图片先被加载而底部的图片后被加载,此时可使用此方法来设置图片加载的优先级。
注意:设置优先级并不能保证图片就一定会被优先加载,只是会偏向倾斜于先加载。
9. .tag()
:
为请求添加标记提升用户体验。比如在列表ListView
的Item
中加载了图片,当用户在快速滑动的时候可以设置停止请求,在滑动停止时再去加载请求,退出当前页面时取消请求。
Picasso
提供了三种设置Tag
的方式:
- 暂停标记:
pauseTag()
- 可见标记:
resumeTag()
- 取消标记:
cancelTag()
在图片请求加载时添加标记:
Picasso.with(mActivity)
.load(Constant.picUrl)
.tag("mark")
.into(mIvNetworkPictures);
ListView
实现滑动监听OnScrollListener
:
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Picasso picasso = Picasso.with(mActivity);
if (scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_TOUCH_SCROLL) {
picasso.resumeTag("mark");
} else {
picasso.pauseTag("mark");
}
}
在页面进行跳转或者退出时取消请求:
@Override
protected void onDestroy() {
super.onDestroy();
Picasso.with(mActivity)
.cancelTag("mark");
}
注意:如果Tag
状态为pause
或者resume
的时候,Picasso
会对Tag
持有一个引用,如果此时用户退出了当前Activity
,垃圾回收机制进行回收的时候就可能会出现内存泄露,所以需要在onDestroy()
方法中进行相应处理。
10. .fetch()
:
该方法会在后台异步加载一张图片,但是不会展示在ImageView
上,也不会返回Bitmap
,这个方法只是为了将获取到的资源加载到本地和内存当中,为后期的加载缩短时间。
11. .get()
:
该方法是一个异步线程,加载完成后会返回一个Bitmap
,但是需要注意的是该方法不能在主线程中调用,因为会造成线程阻塞。
12. Target
:
之前调用into()
方法是将获取到的资源加载到ImageView
中,但我们还可以将资源作为回调放到Target
中。
private Target target = new Target() {
@Override
public void