Picasso
是Square公司推出的一个开源的图片缓存下载库
为什么要使用picasso?
Android系统作为图片资源加载的主角,它是通过图像的像素点来把图像加载到内存中的;现在一张500W的摄像头拍出的照片(2592x1936),加载到内存中需要大约19M的内存;如果你加入了信号强度不一的网络中进行了复杂的网络请求,并进行图片的缓存与其他处理,你会耗费大量的时间与精力来处理这些问题,但如果用了Picasso, 这些问题都一消而散;
项目导入picass:可以去picasso官网下载最新的jar包 http://square.github.io/picasso/
也可以在Android studio中添加
compile 'com.squareup.picasso:picasso:2.5.2'
从网络加载图片
Picasso使用简单易用的接口,并有一个实现类Picasso
,一个完整的功能请求至少需要三个参数;
with(Context context)
-Context
上下文在很多Android Api中都是必须的load(String imageUrl)
- 图片网络加载地址into(ImageView targetImageView)
- 想进行图片展示的ImageView
从本地加载图片时,只需要将load()方法中参数改为资源id 或者路径即可,十分方便,灵活
当图片加载错误时
Picasso给了我们两种解决方案:
- 在判断为空的地址时,取消网络请求,调用
cancelRequest()
,然后调用imageView.setImageDrawable(null)
- 或者调用Picasso的
.placeHolder()
方法进行图片的替换展示 - 如果图片网址错误,我们也可以调用
.error()
方法进行图片替换@Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView==null){ convertView = View.inflate(context,R.layout.item_picasso,null); } ImageView imageView = (ImageView)convertView; if (TextUtils.isEmpty(imageUrls[position])){ Picasso .with(context) .cancelRequest(imageView); imageView.setImageDrawable(null); }else { //加载图片 Picasso .with(context) .load(imageUrls[position]) .placeholder(R.mipmap.ic_launcher) .error(R.mipmap.ic_launcher) .into((ImageView) convertView); } return convertView; }
注意:
.placeholder()
与.error()
所传的参数与.load()
相同
调用noFade()
Picasso的默认图片加载方式有一个淡入的效果,如果调用了noFade()
,加载的图片将直接显示在ImageView
上
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .placeholder(R.mipmap.ic_launcher) .error(R.mipmap.future_studio_launcher) .noFade() .into(imageViewFade);
调用.noPlaceholder()
有一个场景,当你从网上加载了一张图片到Imageview
上,过了一段时间,想在同一个ImageView
上展示另一张图片,这个时候你就会去调用Picasso,进行二次请求,这时Picasso就会把之前的图片进行清除,可能展示的是.placeholder()
的图片,给用户并不是很好的体验,如果调用了noPlaceholder()
,就不会出现这种情况.
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .placeholder(R.mipmap.ic_launcher) .into(imageViewNoPlaceholder, new Callback() { @Override public void onSuccess() { // 当上次加载完成后,进行二次加载 Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[1]) .noPlaceholder() .into(imageViewNoPlaceholder); } @Override public void onError() { } });
调用resize(x,y)来自定义图片的大小
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .resize(600, 200) .into(imageViewResize);
对图片进行处理
如果图片被操作了,可能在展示的时候就会比较丑,我们是想改变这种情景的,Picasso给我们提供了两种选择进行图片展示,centerCrop()
或者 centerInside()
.
-
centerCrop()
- 图片会被剪切,但是图片质量看着没有什么区别 -
Inside()
- 图片会被完整的展示,可能图片不会填充满
ImageView`,也有可能会被拉伸或者挤压Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .resize(600, 200) .centerInside() 或者调用 .centerCrop() .into(imageViewResizeCenterInside);
设置图片加载优先级.poriority()方法
如果一个屏幕上顶部图片较大,而底部图片较小,因为Picasso是异步加载,所以小图会先加载出来,但是对于用户来说,更希望看到的是上面的图片先加载,底部的图片后加载,Picasso支持设置优先级,分为HIGH
, MEDIUM
, 和 LOW
,所有的加载默认优先级为MEDIUM
;
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .fit() .priority(Picasso.Priority.HIGH) .into(imageViewHero);
对图片进行旋转
当我们对一张图片需要进行简单的旋转处理时,只需要调用传入旋转的角度,大于0小于360即可
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .rotate(90f) //旋转90度 .into(imageViewSimpleRotate);
因为图片的旋转都是相对(0,0)进行操作,所以如果我们想自定义相对于某个点,也是可以的,只需要调用 .rotate(float degrees, float pivotX, float pivotY)
Picasso
.with(context)
.load(R.drawable.floorplan)
.rotate(45f, 200f, 100f)
.into(imageViewComplexRotate);
对图片进行转换 Transformation
我们可以在一张图片进行展示之前,对其进行操作,然后在展示;这时我们需要定义一个类实现Transformation
,然后重写里面重要的方法,直接上代码:
public class BlurTransformation implements Transformation { RenderScript rs; public BlurTransformation(Context context) { super(); rs = RenderScript.create(context); } @Override public Bitmap transform(Bitmap bitmap) { // 创建一个Bitmap作为最后处理的效果Bitmap Bitmap blurredBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); // 分配内存 Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SHARED); Allocation output = Allocation.createTyped(rs, input.getType()); // 根据我们想使用的配置加载一个实例 ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setInput(input); // 设置模糊半径 script.setRadius(10); //开始操作 script.forEach(output); // 将结果copy到blurredBitmap中 output.copyTo(blurredBitmap); //释放资源 bitmap.recycle(); return blurredBitmap; } @Override public String key() { return "blur"; } } //然后调用即可 Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .transform(new BlurTransformation(context)) .into(imageViewTransformationBlur);
关于缓存机制
Picasso默认的缓存分配大小特点:
- LRU缓存占应用程序可用内存的15%
- 本地缓存占到硬盘空间的2%但不超过50M并且不小于5M(前提是这种情况只在4.0以上有效果,或者你能像OKHttp那样提供一个本地缓存库来支持全平台)
- Picasso默认开启3个线程来进行本地与网络之间的访问
- Picasso加载图片顺序, 内存–>本地–>网络
查看图片来源
想知道我们所加载的图片来源于何处,是内存,本地还是从网络加载的,当然这个动作Picasso已经为我们想好了,我们只需要在请求的时候调用.setIndicatorsEnabled(true)
Picasso .with(context) .setIndicatorsEnabled(true);
这样每张图片在显示的时候,左上角都会有一个小标记,分别又三种三色,蓝色,绿色,红色;
- 蓝色 - 从内存中获取,是最佳性能展示
- 绿色 - 从本地获取,性能一般
- 红色 - 从网络加载,性能最差
最后 A powerful image downloading and caching library for Android