您好,登錄后才能下訂單哦!
今天開始我們來學習一下Picasso,計劃包括以下幾方面的內容:
圖片加載利器之Picasso進階
圖片加載利器之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);
效果圖如下
可以看到圖片的左上角有個藍色的三角形,表示該圖片是從磁盤加載的,另外如果為紅色則表示從網絡加載,如果為綠色表示從內存加載。
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的更高級的用法,通過擴展實現更加豐富的功能。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。