0
点赞
收藏
分享

微信扫一扫

【Android -- 开源库】Picasso 的基本使用

一、简介

Android 中有几个比较有名的图片加载框架,Universal ImageLoader、Picasso、Glide 和 Fresco。Picasso 是 Square 公司开源的 Android 端的图片加载和缓存框架。Square 真是一家良心公司啊,为我们 Android 开发者贡献了很多优秀的开源项目有木有!像什么 Rerefoit 、OkHttp、LeakCanary、Picasso 等等都是非常火的开源项目。
【Android -- 开源库】Picasso 的基本使用_优先级

二、实战

1. 在 app/build.gradle 中添加依赖:

// picasso
implementation 'com.squareup.picasso:picasso:2.71828'

2. 加载显示图片
将 Picasso 添加到项目之后,我们就可以用它来加载图片了,使用方法非常简单:

Picasso.get()
.load("http://ww3.sinaimg.cn/large/610dc034jw1fasakfvqe1j20u00mhgn2.jpg")
.into(mImageView);

上面演示了加载一张网络图片,它还支持其它形式的图片加载,加载文件图片,加载本地资源图片,加载一个Uri 路径给的图片,提供了几个重载的方法:

  • 加载一个以 Uri 路径给的图片
Uri uri = Uri.parse(ANDROID_RESOURCE + context.getPackageName() + FOREWARD_SLASH + resourceId);

Picasso.get().load(uri).into(mImageView);
  • 加载 File 中的图片
Picasso.get().load(file).into(mImageView);
  • 加载本地资源图片
Picasso.get().load(R.mipmap.ic_launcher).into(mImageView);

3. 占位图
我们的项目中通常最常用的就是加载网络图片,但是由于网络环境的差异,有时侯加载网络图片的过程有点慢,这样界面上就会显示空ImageView什么也看不见,用户体验非常不好。

  • placeholder
    提供一张在网络请求还没有完成时显示的图片,它必须是本地图片,代码如下:
Picasso.get()
.load(URL)
.placeholder(R.drawable.default_bg)
.into(mImageView);
  • error
    提供一张在加载图片出错的情况下显示的默认图:
Picasso.get()
.load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.into(mImageView);
  • noPlaceholder
    在调用 into 的时候明确告诉你没有占位图设置。注意: placeholder 和 noPlaceholder 不能同时应用在同一个请求上,会抛异常。
Picasso.get()
.load(URL)
.noPlaceholder()
.error(R.drawable.error_iamge)
.into(mImageView);
  • noFade
    无论你是否设置了占位图,Picasso 从磁盘或者网络加载图片时,into 显示到 ImageView 都会有一个简单的渐入过度效果,让你的 UI 视觉效果更柔顺丝滑一点,如果你不要这个渐入的效果(没有这么坑爹的需求吧!!!),就调用 noFade 方法。
Picasso.get()
.load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.noFade()
.into(mImageView);

4. 设置图片尺寸(Resize)、缩放(Scale)和裁剪(Crop)

  • Resize(int w,int h)
    在项目中,为了带宽、内存使用和下载速度等考虑,服务端给我们的图片的 size 应该和我们 View 实际的 size 一样的,但是实际情况并非如此,服务端可能给我们一些奇怪的尺寸的图片,我们可以使用 resize(int w,int hei) 来重新设置尺寸。
Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.resize(400,200)
.into(mImageView);

resize() 方法接受的参数的单位是 pixels ,还有一个可以设置 dp 单位的方法,将你的尺寸写在 dimens.xml 文件中,然后用 resizeDimen(int targetWidthResId, int targetHeightResId) 方法。

<dimen name="image_width">300dp</dimen>
<dimen name="image_height">200dp</dimen>
Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.resize(R.dimen.image_width,R.dimen.image_height)
.into(mImageView);
  • onlyScaleDown
    当调用了 resize 方法重新设置图片尺寸的时候,调用 onlyScaleDown 方法,只有当原始图片的尺寸大于我们指定的尺寸时,resize 才起作用如:
Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.resize(4000,2000)
.onlyScaleDown()
.into(mImageView);

只有当原来的图片尺寸大于 4000 x 2000 的时候,resize 才起作用。

  • 图片裁剪 centerCrop()
    Picasso 给我们提供了一个方法,centerCrop,充满 ImageView 的边界,居中裁剪。
Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.resize(400,200)
.centerCrop()
.into(mImageView);
  • centerInside
    上面的 centerCrop 是可能看不到全部图片的,如果你想让 View 将图片展示完全,可以用 centerInside ,但是如果图片尺寸小于 View 尺寸的话,是不能充满 View 边界的。
Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.resize(400,200)
.centerInside()
.into(mImageView);
  • fit
    它会自动测量我们的 View 的大小,然后内部调用 reszie 方法把图片裁剪到 View 的大小,这就帮我们做了计算 size 和调用 resize 这2步。最好配合前面的 centerCrop 使用。代码如下:
Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.fit()
.centerCrop()
.into(mImageView);

特别注意:
1,fit 只对 ImageView 有效
2,使用fit时,ImageView 宽和高不能为 wrap_content ,很好理解,因为它要测量宽高。

  • 图片旋转 Rotation()
    在图片显示到 ImageView 之前,还可以对图片做一些旋转操作,调用 rotate(int degree) 方法:
Picasso.get()
.load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.rotate(180)
.into(mImageView);

这个方法它是以(0,0)点旋转,但是有些时候我们并不想以(0,0)点旋转,还提供了另外一个方法可以指定原点:

Picasso.get()
.load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.rotate(180,200,100)
.into(mImageView);

5. 转换器 Transformation
Transformation 这就是 Picasso 的一个非常强大的功能了,它允许你在 load 图片 -> into ImageView 中间这个过成对图片做一系列的变换。比如你要做图片高斯模糊、添加圆角、做度灰处理、圆形图片等等都可以通过 Transformation 来完成。
a) 首先定义一个转换器继承 Transformation

public static class BlurTransformation implements Transformation{

RenderScript rs;

public BlurTransformation(Context context) {
super();
rs = RenderScript.create(context);
}

@Override
public Bitmap transform(Bitmap bitmap) {
// Create another bitmap that will hold the results of the filter.
Bitmap blurredBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

// Allocate memory for Renderscript to work with
Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SHARED);
Allocation output = Allocation.createTyped(rs, input.getType());

// Load up an instance of the specific script that we want to use.
ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
script.setInput(input);

// Set the blur radius
script.setRadius(25);

// Start the ScriptIntrinisicBlur
script.forEach(output);

// Copy the output to the blurred bitmap
output.copyTo(blurredBitmap);

bitmap.recycle();

return blurredBitmap;
}

@Override
public String key() {
return "blur";
}
}

b) 加载图片的时候,在into 方法前面调用 transform方法 应用Transformation

Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.transform(new BlurTransformation(this))
.into(mBlurImage);

需求:我想先做个度灰处理然后在做一个高斯模糊图。
a. 度灰的 Transformation

public static class GrayTransformation implements Transformation{

@Override
public Bitmap transform(Bitmap source) {
int width, height;
height = source.getHeight();
width = source.getWidth();

Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(source, 0, 0, paint);

if(source!=null && source!=bmpGrayscale){
source.recycle();
}
return bmpGrayscale;
}

@Override
public String key() {
return "gray";
}
}

如果是多个Transformation操作,有 2 种方式应用。
方式一:直接调用多次 transform 方法,不会覆盖的。

List<Transformation> transformations = new ArrayList<>();
transformations.add(new GrayTransformation());
transformations.add(new BlurTransformation(this));

Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.fit()
.centerCrop()
.transform(transformations)
.into(mBlurImage);

方式二:接受一个 List,将 Transformation 放大 list 里

List<Transformation> transformations = new ArrayList<>();
transformations.add(new GrayTransformation());
transformations.add(new BlurTransformation(this));

Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.fit()
.centerCrop()
.transform(transformations)
.into(mBlurImage);

另外发现了一个开源库,专门写了很多好玩的Transformation,有兴趣的可以看一下:
​​​picasso-transformations​​

6. 请求优先级
Picasso 为请求设置有优先级,有三种优先级,LOW、NORMAL、HIGH。默认情况下都是 NORMAL,除了调用 fetch 方法,fetch 方法的优先级是LOW。

public enum Priority {
LOW,
NORMAL,
HIGH
}

可以通过priority方法设置请求的优先级,这会影响请求的执行顺序,但是这是不能保证的,它只会往高的优先级靠拢。代码如下:

Picasso.get().load(URL)
.placeholder(R.drawable.default_bg)
.error(R.drawable.error_iamge)
.priority(Picasso.Priority.HIGH)
// .priority(Picasso.Priority.LOW)
.into(mImageView);

7. 同步/异步加载图片
1,同步加载图片
很简单,同步加载使用get() 方法,返回一个Bitmap 对象,代码如下:

try {
Bitmap bitmap = Picasso.with(this).load(URL).get();
} catch (IOException e) {
e.printStackTrace();
}

注意:使用同步方式加载,不能放在主线程来做。

2,异步加载图片
一般直接加载图片通过 into 显示到 ImageView 是异步的方式,除此之外,还提供了 2 个异步的方法:

Picasso.get().load(URL).fetch(new Callback() {
@Override
public void onSuccess() {
//加载成功
}

@Override
public void onError() {
//加载失败
}
});

参考
​​​Picasso官网​​​​Picasso — Getting Started​​


举报

相关推荐

0 条评论