Android圖片加載利器之Picasso基本用法
今天開始我們來學(xué)習(xí)一下Picasso,計(jì)劃包括以下幾方面的內(nèi)容:
圖片加載利器之Picasso進(jìn)階
圖片加載利器之Picasso源碼解析
目前市場上比較流行的圖片加載框架主要有UniversalImageLoader,Picasso,Glide,F(xiàn)resco。
下面簡單介紹一下這幾個(gè)框架:
UniversalImageLoader:這個(gè)可以說是非常非常經(jīng)典的一個(gè)了,相信每個(gè)app的開發(fā)人員都使用過,只可惜作者已經(jīng)停止該項(xiàng)目的維護(hù)了,所以不太推薦使用。
Picasso:是Square公司出品的圖片加載框架,Square出品必出精品,主要特點(diǎn)就是使用簡單,擴(kuò)展性強(qiáng),支持各種來源的圖片,包括網(wǎng)絡(luò)、Resources、assets、files、content providers等。內(nèi)部集成了OkHttp的網(wǎng)絡(luò)框架,所以如果你的項(xiàng)目中使用了Square公司的其他框架,那么推薦使用Picasso,兼容性會(huì)好一些。目前在Github上的Star已經(jīng)達(dá)到12758個(gè)。
Glide:是Google員工的開源項(xiàng)目,基于Picasso的一個(gè)框架,代碼風(fēng)格與Picasso非常相似,增加了更多的功能,非常重要的就是支持gif,當(dāng)然它的包會(huì)大一些。如果你的項(xiàng)目對(duì)圖片的使用場景非常多,并且需要支持gif,則推薦使用。目前在Github上的Star已經(jīng)達(dá)到13636個(gè)。
Fresco:是FB出品的開源框架,比較新,最大的優(yōu)點(diǎn)就是在內(nèi)存占用上的優(yōu)化,極大的減少了OOM,功能上也包含了以上三種框架的功能,但是也帶來了一個(gè)比較明顯的缺點(diǎn)就是太大了,所以推薦使用在完全是做圖片相關(guān)的app上,否則Picasso和Glide就完全夠用了。目前在Github上的Star已經(jīng)達(dá)到11983個(gè)。
上面主要對(duì)各種框架做個(gè)簡單的介紹,既然是講解Picasso的,那么接下來看看Picasso都有哪些功能。
1 提供內(nèi)存和磁盤緩存,默認(rèn)開啟,可以設(shè)置不進(jìn)行緩存
2 圖片加載過程中默認(rèn)顯示的圖片
3 圖片加載失敗或出錯(cuò)后顯示的圖片
4 圖片加載成功或失敗的回調(diào)
5 自定義圖片大小、自動(dòng)測量ImageView大小、裁剪、旋轉(zhuǎn)圖片等
6 對(duì)圖片進(jìn)行轉(zhuǎn)換
7 標(biāo)簽管理,暫停和恢復(fù)圖片加載
8 請(qǐng)求優(yōu)先級(jí)管理
9 可以從不同來源加載圖片,網(wǎng)絡(luò)、Resources、assets、files、content providers
10 更加豐富的擴(kuò)展功能
以上這些功能將會(huì)在下面的文章中進(jìn)行詳細(xì)講解。
上面我們提到了Picasso的諸多功能,下面我們來分別演示一下這些功能
配置:
在build.gradle中添加引用
dependencies { ... compile 'com.squareup.picasso:picasso:2.5.2' ... }
1 加載圖片
通過源碼可以發(fā)現(xiàn)load方法主要要以下幾種重載
load(Uri uri) load(String path) load(File file) load(int resourceId)
//定義一張網(wǎng)絡(luò)圖片的uri,其實(shí)就是上面的測試圖片 private static final String imageUrl = "imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"; ImageView imageView = (ImageView) findViewById(R.id.imageView); //從網(wǎng)絡(luò)加載圖片 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);
超級(jí)簡單有木有,這里面只演示了兩種方式。
2 加載過程中顯示默認(rèn)圖片placeholder
Picasso.with(this).load(imageUrl).placeholder(R.mipmap.default_image).into(imageView);
一般網(wǎng)絡(luò)加載圖片耗時(shí)比較長,所以會(huì)先默認(rèn)顯示一張?zhí)娲膱D片,只支持resId和Drawable本地圖片。
3 加載失敗后顯示錯(cuò)誤的圖片
Picasso.with(this).load(imageUrl+"landptf").error(R.mipmap.default_image).into(imageView);
為了顯示錯(cuò)誤圖片,這里面我在正確的地址后面拼了字符串構(gòu)造了一個(gè)錯(cuò)誤的地址,同樣只支持本地的圖片
4 圖片填充方式
4.1 fit()
Picasso.with(this).load(imageUrl).fit().into(imageView);
該屬性會(huì)根據(jù)Image View的大小充滿整個(gè)View,不考慮比例,可能造成圖片的拉伸或者縮小
4.2 centerCrop()
Picasso.with(this).load(imageUrl).resize(320, 640).centerCrop().into(imageView);
按比例裁減圖片,使其居中顯示,充滿View,會(huì)造成圖片顯示不全,必須與resize方法同時(shí)使用
4.3 centerInside()
Picasso.with(this).load(imageUrl).resize(320, 640).centerInside().into(imageView);
按比例裁減圖片,圖片可以完全顯示,但如果圖片比View小,則無法充滿整個(gè)View,必須與resize方法同時(shí)使用
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);
默認(rèn)情況下圖片顯示出來都會(huì)有一個(gè)過渡的效果,添加.noFade方法后,可以使該取消該效果,基本上很少使用
6 圖片旋轉(zhuǎn)rotate()
//以(0,0)為中心順時(shí)針旋轉(zhuǎn)45度 Picasso.with(this).load(imageUrl).rotate(45).into(imageView); //以(64,64)為中心順時(shí)針旋轉(zhuǎn)45度 Picasso.with(this).load(imageUrl).rotate(45, 64, 64).into(imageView);
7 緩存策略
Picasso提供緩存的調(diào)試方法,通過如下代碼可設(shè)置
Picasso.with(this).setIndicatorsEnabled(true);
效果圖如下
可以看到圖片的左上角有個(gè)藍(lán)色的三角形,表示該圖片是從磁盤加載的,另外如果為紅色則表示從網(wǎng)絡(luò)加載,如果為綠色表示從內(nèi)存加載。
Picasso的緩存流程是先檢查內(nèi)存是否有保存該圖片,如果沒有則檢查磁盤是否有保存該圖片,如果沒有則從網(wǎng)絡(luò)下載,下載成功之后分別保存到內(nèi)存和磁盤上各一份,如果我們有時(shí)候不想緩存該圖片或者不想從緩存獲取圖片,該如何呢?Picasso也給我買提供了相應(yīng)的控制方法。
Picasso.with(this) .load(imageUrl) .skipMemoryCache() .into(imageView); Picasso.with(this) .load(imageUrl) .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) .into(imageView);
上面兩個(gè)方法完全等價(jià),但是第一種寫法官方已經(jīng)不推薦使用了,這里面列出來只是讓大家了解一下。
這個(gè)表示什么意思呢?跳過從內(nèi)存加載圖片,并且圖片下載之后也不在內(nèi)存中進(jìn)行緩存。
也就是圖片的左上角的標(biāo)識(shí)永遠(yuǎn)不可能為綠色。
MemoryPolicy.NO_CACHE:直接跳過檢查內(nèi)存是否有緩存該圖片
MemoryPolicy.NO_STORE:圖片下載之后不在內(nèi)存中進(jìn)行緩存
Picasso.with(this) .load(imageUrl) .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE) .into(imageView);
同理該方法表示跳過從磁盤加載圖片,并且圖片下載之后也不在磁盤中進(jìn)行緩存。
這里注意只是不在磁盤中緩存,但是會(huì)在內(nèi)存中緩存,因此若內(nèi)存和磁盤中都不想緩存則需要和兩個(gè)方法共同使用,如下:
Picasso.with(this) .load(imageUrl) .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE) .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) .into(imageView);
NetworkPolicy枚舉中還有一個(gè)值OFFLINE,這個(gè)表示強(qiáng)制從緩存中取,不會(huì)發(fā)起網(wǎng)絡(luò)請(qǐng)求,如果緩存中沒有也不會(huì)從網(wǎng)絡(luò)中請(qǐng)求。
8 優(yōu)先級(jí)priority
設(shè)想一種場景,當(dāng)我們打開一個(gè)界面的時(shí)候,界面上有列表,每個(gè)列表項(xiàng)都有圖片需要加載,列表上面還有一張圖片需要提前加載,那么怎樣來調(diào)度每個(gè)請(qǐng)求的優(yōu)先級(jí)呢?
Picasso給我們提供了priority方法來管理請(qǐng)求的優(yōu)先級(jí)
public enum Priority { LOW, NORMAL, HIGH }
通過priority方法的注釋中可以知道默認(rèn)的優(yōu)先級(jí)是NORMAL,因此我們可以如下實(shí)現(xiàn)高優(yōu)先級(jí)加載:
Picasso.with(this) .load(imageUrl) .priority(Picasso.Priority.HIGH) .into(imageView);
9 tag標(biāo)簽管理
使用過list加載圖片的童鞋都知道在列表滾動(dòng)過程中停止加載圖片,停止?jié)L動(dòng)時(shí)恢復(fù)圖片加載,那么這樣的功能在Picasso中時(shí)如何實(shí)現(xiàn)的呢?
這就用到了tag標(biāo)簽的功能
通過如下代碼設(shè)置tag:
Picasso.with(this).load(imageUrl).tag("landptf").into(imageView);
在Picasso類中提供了如下幾個(gè)方法來控制tag
cancelTag(Object tag) pauseTag(Object tag) resumeTag(Object tag)
通過名字可以很好理解了,我們在列表滾動(dòng)的時(shí)候調(diào)用
Picasso.with(this).pauseTag("landptf");
在停止?jié)L動(dòng)的時(shí)候調(diào)用
Picasso.with(this).resumeTag("landptf");
至于cancelTag用于取消下載,一般我們在Activity銷毀的時(shí)候?qū)⑽赐瓿傻恼?qǐng)求取消。
Picasso.with(this).cancelTag("landptf");
10 手動(dòng)指定key值stableKey
Picasso.with(this).load(imageUrl).stableKey("landptf").into(imageView);
我們猜想一個(gè)問題,Picasso是如何知道是否有緩存圖片的,一般根據(jù)key值來判斷,那么這個(gè)key值又是如何生成的呢?通過閱讀源碼可以知道,根據(jù)傳入的uri或者resourceId,是否設(shè)置了旋轉(zhuǎn)角度,是否設(shè)置了resize,或者是centerCrop還是centerInside等拼接出來的字符串,這里面我們可以通過stableKey方法來替換傳入的uri或者resourceId生成key值。
好了,這篇文章就講到這里了,在下一篇文章中我們將會(huì)繼續(xù)學(xué)習(xí)Picasso的更高級(jí)的用法,通過擴(kuò)展實(shí)現(xiàn)更加豐富的功能。
- 詳解Android?GLide圖片加載常用幾種方法
- Android圖片加載框架Coil的詳細(xì)使用總結(jié)
- Android 官推 kotlin-first 的圖片加載庫——Coil的使用入門
- Android編程圖片加載類ImageLoader定義與用法實(shí)例分析
- Android基于Glide v4.x的圖片加載進(jìn)度監(jiān)聽
- Android ListView實(shí)現(xiàn)ImageLoader圖片加載的方法
- Android中RecyclerView 滑動(dòng)時(shí)圖片加載的優(yōu)化
- Android圖片加載框架Glide的基本用法介紹
- 如何在Android中高效管理圖片加載
相關(guān)文章
android電源信息查看(電量、溫度、電壓)實(shí)例代碼
這篇文章主要介紹了android電源信息查看方法,以實(shí)例形式較為詳細(xì)的分析了Android實(shí)現(xiàn)電源電量、電壓、溫度等信息查看的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Android編程使用光線傳感器獲取光線強(qiáng)弱的方法【LightSensorManager封裝類】
這篇文章主要介紹了Android編程使用光線傳感器獲取光線強(qiáng)弱的方法,結(jié)合實(shí)例形式分析了Android光線傳感器管理封裝類LightSensorManager的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-11-11Android學(xué)習(xí)教程之動(dòng)態(tài)GridView控件使用(6)
這篇文章主要為大家詳細(xì)介紹了Android動(dòng)態(tài)GridView控件的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11詳解Android Studio正式簽名進(jìn)行調(diào)試的實(shí)現(xiàn)步驟
這篇文章主要介紹了詳解Android Studio正式簽名進(jìn)行調(diào)試的實(shí)現(xiàn)步驟的相關(guān)資料,需要的朋友可以參考下2017-07-07Android編程實(shí)現(xiàn)壓縮圖片并加載顯示的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)壓縮圖片并加載顯示的方法,涉及Android開發(fā)中圖片的運(yùn)算、壓縮處理操作及界面布局顯示壓縮圖片等相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-10-10Android 使用版本控制工具時(shí)添加忽略文件的方式(詳解)
下面小編就為大家?guī)硪黄狝ndroid 使用版本控制工具時(shí)添加忽略文件的方式(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01android?studio項(xiàng)目:綁定服務(wù)和線程實(shí)現(xiàn)計(jì)時(shí)器
這篇文章主要介紹了android?studio項(xiàng)目:綁定服務(wù)和線程實(shí)現(xiàn)計(jì)時(shí)器,完成一個(gè)秒表,具備啟停功能,通過綁定服務(wù)實(shí)現(xiàn)功能,通過Thread+handler更新界面,需要的朋友可以參考一下2021-12-12Android倒計(jì)時(shí)的開始與停止 剩余時(shí)分秒的展示
這篇文章主要為大家詳細(xì)介紹了Android倒計(jì)時(shí)的開始與停止,剩余時(shí)分秒的展示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09