- 原文鏈接: Placeholders, Errors and Fading
- 原文作者: Future Studio
- 譯文出自: 小鄧子的簡書
- 譯者: 小鄧子
- 狀態: 完成
預加載占位圖: .placeholder()
我們甚至不用解釋或者討論:一個空的ImageView
在視覺體驗上真的很差,因為這是毋庸置疑的。如果你使用Picasso,你可能更傾向于通過網絡連接來加載圖像。依賴于你所處的網絡環境,加載過程可能需要大量時間。一個比較優雅的方式就是先放置一個占位圖,直到真正的圖像被加載和處理完成之后,再進行替換。
Picasso的流式接口調用方式讓操作變得異常簡單。只需要調用.placeHolder()
,并傳入一個Drawable的資源引用,它就會先展示這個占位圖,直到真正的圖像準備好。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.placeholder(R.mipmap.ic_launcher) // can also be a drawable
.into(imageViewPlaceholder);
出于明顯的理由,不能把一個網絡地址作為占位圖,因為一旦占位圖需要時間下載便失去了它原本的意義。App本身的資源文件是很方便使用和訪問的。然而,對于.load()
來說,Picasso能夠接受各種參數值,因此可能出現不可加載(如,無網絡鏈接,服務器宕機等),資源被刪除或者無訪問權限等現象。下一節中,我們將討論如何使用異常占位圖。
異常占位圖: .error()
假設我們的應用需要從一個網站加載圖像,不幸的是,這個網站目前宕機了。Picasso確實為我們提供了一個處理異常的回調,來應對這種情況的發生。但是對于現在來講,它的實現或許有些復雜,因此我們會在隨后的文章對其討論。其實在大多數場景中,使用一個特殊的占位圖來標識那些不能被加載的圖像,顯然是足夠的。
使用方式與前面講到的設置預加載占位圖一樣,唯一不同的是我們要調用是.error()
函數。
Picasso
.with(context)
.load("http://futurestud.io/non_existing_image.png")
.placeholder(R.mipmap.ic_launcher) // can also be a drawable
.error(R.mipmap.future_studio_launcher) // will be displayed if the image cannot be loaded
.into(imageViewError);
就是這樣!如果你定義在.load()
中的值不能被加載,Picasso將會展示R.mipmap.future_studio_launcher
。再次強調,.error()
中所能接受的參數只能是已經初始化的drawable對象或指向資源的引用(如,R.drawable.<drawable-keyword>)。
noFade()的運用
無論你是要在加載完成之前展示一個展位圖還是其他,Picasso為了讓UI視圖的改變更加揉和,會使用一個漸變效果將圖像添加到ImageView
上。如果你希望直接展示圖像而不需要這種漸變效果,可以在Picasso請求上調用.noFade()
。
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.placeholder(R.mipmap.ic_launcher) // can also be a drawable
.error(R.mipmap.future_studio_launcher) // will be displayed if the image cannot be loaded
.noFade()
.into(imageViewFade);
這將會直接顯示你的圖片,ImageView
上將不會看到任何的漸變效果。請確保你有充分的理由這樣做!
重要的是要知道,這些方法的調用彼此之間不需要相互依賴,也就是說,你可以只使用.error()
,而不調用.placeholder()
。任意的流式調用組合都是有可能的。
noPlaceholder()的運用
最后,你可能在文檔中發現了.noPlaceholder()
這個函數。了解它很重要,因為這個調用會禁用之前通過.placeholder()
或者.error()
傳入的占位圖。因此它也涵蓋著不同的使用場景。
讓我們考慮一下這個場景:你想為一個ImageView
加載圖像,一段時間之后,你又想為這個ImageView
加載另一個圖像。在默認配置條件下,你創建第二次Picasso調用的時候,ImageView
將會清除之前的圖像并顯示通過.placeholder()
設置的占位圖。如果ImageView
上的圖像在數秒內發生了連續變化,你的用戶不僅會感到困惑而且也很影響體驗。更好的解決辦法就是在第二次Picasso請求上調用.noPlaceholder()
。這樣就能一直保持之前的圖像直到第二次加載完成。從而獲得更更舒服的用戶體驗。
// load an image into the imageview
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.placeholder(R.mipmap.ic_launcher) // can also be a drawable
.into(imageViewNoPlaceholder, new Callback() {
@Override
public void onSuccess() {
// once the image is loaded, load the next image
Picasso
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[1])
.noPlaceholder() // but don't clear the imageview or set a placeholder; just leave the previous image in until the new one is ready
.into(imageViewNoPlaceholder);
}
@Override
public void onError() {
}
});
這段代碼片精準的做到了我們的期望。當第一個圖像加載完成后,立即開始第二個圖像加載請求。然而,由于.noPlaceholder()
的使用,它在恰當的時機保持了之前的圖像不變。