欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android图片加载利器之Picasso基本用法

程序员文章站 2023-11-12 21:55:46
今天开始我们来学习一下picasso,计划包括以下几方面的内容: 图片加载利器之picasso进阶 图片加载利器之picasso源码解析 目前市场上比较流行的...

今天开始我们来学习一下picasso,计划包括以下几方面的内容:

图片加载利器之picasso进阶
图片加载利器之picasso源码解析

Android图片加载利器之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的诸多功能,下面我们来分别演示一下这些功能

配置:

在build.gradle中添加引用

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);

效果图如下

Android图片加载利器之Picasso基本用法

可以看到图片的左上角有个蓝色的三角形,表示该图片是从磁盘加载的,另外如果为红色则表示从网络加载,如果为绿色表示从内存加载。

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)
 .networkpolicy(networkpolicy.no_cache, networkpolicy.no_store)
 .into(imageview);

同理该方法表示跳过从磁盘加载图片,并且图片下载之后也不在磁盘中进行缓存。
这里注意只是不在磁盘中缓存,但是会在内存中缓存,因此若内存和磁盘中都不想缓存则需要和两个方法共同使用,如下:

picasso.with(this)
 .load(imageurl)
 .networkpolicy(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的更高级的用法,通过扩展实现更加丰富的功能。