前言
Fresco 庫(kù)已經(jīng)出來好長(zhǎng)時(shí)間了涛酗,雖然我們的項(xiàng)目里也在用秸谢,但是一直沒有時(shí)間去好好研究一下(吐槽:不是沒有時(shí)間愧捕,是懶)肃续。趁著項(xiàng)目迭代的間隙時(shí)間來好好了解一下這個(gè)庫(kù)的使用黍檩,以便以后的使用有文檔可尋。在這里也默默的決定以后要好好利用時(shí)間始锚,多了解一些新的知識(shí)刽酱,轉(zhuǎn)化為自己的東西。多說無益瞧捌,直接開始棵里。
Fresco 簡(jiǎn)介
我們首先介紹一下 Fresco 這個(gè)庫(kù)。Fresco 是 FaceBook 開源的一個(gè)項(xiàng)目姐呐,是應(yīng)用于圖片加載的庫(kù)殿怜,簡(jiǎn)稱圖片加載庫(kù)。該庫(kù)自帶緩存曙砂,支持GIF头谜,WebP,縮略圖···圖片的緩存管理對(duì)5.0以下支持的也很好鸠澈。同時(shí)還支持很多的特效處理柱告,一般的效果都可以實(shí)現(xiàn)⌒Τ拢可惜的是只能使用該庫(kù)自己的控件际度。Fresco 默認(rèn)試用的 HttpURLConnection 作為網(wǎng)絡(luò)層,我們也可以自己設(shè)置網(wǎng)絡(luò)庫(kù)新锈,可以說非常方便甲脏。
相關(guān)文檔推薦
Fresco 官方文檔:https://www.fresco-cn.org/
Fresco 開源地址:https://github.com/facebook/fresco
Fresco 使用步驟
接下來我們一步一步的說明使用的步驟眶熬。
導(dǎo)包
compile 'com.facebook.fresco:fresco:1.1.0'
//如果支持 GIF 圖需要導(dǎo)包妹笆,注意后面的版本號(hào)
compile 'com.facebook.fresco:animated-gif:0.12.0'
初始化
你只需要調(diào)用Fresco.initialize一次即可完成初始化块请,在 Application 里面做這件事再適合不過了(如下面的代碼),注意多次的調(diào)用初始化是無意義的
初始化時(shí)拳缠,可以指定相應(yīng)的緩存路徑和使用的網(wǎng)絡(luò)層墩新,這個(gè)后面會(huì)講,現(xiàn)在我們就可以進(jìn)行試用了窟坐。
SimpleDraweeView 的使用
SimpleDraweeView 是 Fresco 最常使用的控件海渊。這里先介紹一下 SimpleDraweeView 的基本屬性:
XML屬性 意義
fadeDuration 淡入淡出動(dòng)畫持續(xù)時(shí)間(單位:毫秒ms)
actualImageScaleType 實(shí)際圖像的縮放類型
placeholderImage 占位圖
placeholderImageScaleType 占位圖的縮放類型
progressBarImage 進(jìn)度圖
progressBarImageScaleType 進(jìn)度圖的縮放類型
progressBarAutoRotateInterval 進(jìn)度圖自動(dòng)旋轉(zhuǎn)間隔時(shí)間(單位:毫秒ms)
failureImage 失敗圖
failureImageScaleType 失敗圖的縮放類型
retryImage 重試圖
retryImageScaleType 重試圖的縮放類型
backgroundImage 背景圖
overlayImage 疊加圖
pressedStateOverlayImage 按壓狀態(tài)下所顯示的疊加圖
roundAsCircle 設(shè)置為圓形圖
roundedCornerRadius 圓角半徑
roundTopLeft 左上角是否為圓角
roundTopRight 右上角是否為圓角
roundBottomLeft 左下角是否為圓角
roundBottomRight 右下角是否為圓角
roundingBorderWidth 圓形或者圓角圖邊框的寬度
roundingBorderColor 圓形或者圓角圖邊框的顏色
roundWithOverlayColor 圓形或者圓角圖底下的疊加顏色(只能設(shè)置顏色)
viewAspectRatio 控件縱橫比
縮放類型—ScaleType:
類型 描述
center 居中,無縮放
centerCrop 保持寬高比縮小或放大哲鸳,使得兩邊都大于或等于顯示邊界臣疑。居中顯示。
focusCrop 同centerCrop, 但居中點(diǎn)不是中點(diǎn)徙菠,而是指定的某個(gè)點(diǎn)
centerInside 使兩邊都在顯示邊界內(nèi)讯沈,居中顯示。如果圖尺寸大于顯示邊界婿奔,則保持長(zhǎng)寬比縮小圖片缺狠。
fitCenter 保持寬高比,縮小或者放大萍摊,使得圖片完全顯示在顯示邊界內(nèi)挤茄。居中顯示
fitStart 同上。但不居中冰木,和顯示邊界左上對(duì)齊
fitEnd 同fitCenter穷劈, 但不居中,和顯示邊界右下對(duì)齊
fitXY 不保存寬高比踊沸,填充滿顯示邊界
none 如要使用tile mode顯示, 需要設(shè)置為none
在使用中我們可以直接選擇需要的屬性進(jìn)行加載圖片
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/iv_test_one"
android:layout_width="130dp"
android:layout_height="130dp"
fresco:placeholderImage="@mipmap/ic_launcher"/>
相應(yīng)的我們需要加載顯示圖片
private SimpleDraweeView image1;
image1 = (SimpleDraweeView) findViewById(R.id.iv_test_one);
image1.setImageURI(url);
怎么樣是不是很簡(jiǎn)單囚衔,當(dāng)然這只是最簡(jiǎn)單和常用的方式,還有很多其他用法雕沿,下面我們會(huì)介紹练湿。這里提醒一下,SimpleDraweeView 是不支持 wrap_content 的审轮,具體原因請(qǐng)看官方文檔肥哎。
加載網(wǎng)絡(luò)圖片(URL,RUI)疾渣,本地圖片(res篡诽,drawable,F(xiàn)ile榴捡,Asset)
接下來我們就各種情況下的圖片進(jìn)行加載顯示杈女。
Fresco 不支持相對(duì)路徑的URI. 所有的 URI 都必須是絕對(duì)路徑,并且?guī)显?URI 的 scheme。
下面是支持各種路徑:
加載網(wǎng)絡(luò)
simpleDraweeView.setImageURI("http://pic31.nipic.com/20130802/7487939_100434185000_2.jpg");
加載本地
simpleDraweeView.setImageResource(R.drawable.local_image);
simpleDraweeView.setImageResource("res://"+ getPackageName() + "/" + R.drawable.local_image);
這里僅僅舉幾個(gè)例子达椰,只要按照上面圖片給的格式加載數(shù)據(jù)即可翰蠢。
特殊效果處理
圓角圖片設(shè)置
//通過 XML 進(jìn)行設(shè)置
roundAsCircle 設(shè)置為圓形圖
roundedCornerRadius 圓角半徑
roundTopLeft 左上角是否為圓角
roundTopRight 右上角是否為圓角
roundBottomLeft 左下角是否為圓角
roundBottomRight 右下角是否為圓角
roundingBorderWidth 圓形或者圓角圖邊框的寬度
roundingBorderColor 圓形或者圓角圖邊框的顏色
roundWithOverlayColor 圓形或者圓角圖底下的疊加顏色(只能設(shè)置顏色)
//設(shè)置一個(gè)圓角半徑為1dp的四個(gè)角均為圓角的圖片
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/iv_beauty_big_pic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
fresco:fadeDuration="300"
fresco:roundAsCircle="false"http://設(shè)置圓形圖片
fresco:roundedCornerRadius="1dp"
fresco:roundTopLeft="true"
fresco:roundTopRight="true"
fresco:roundBottomLeft="true"
fresco:roundBottomRight="true"
fresco:viewAspectRatio="1.33"
/>
//通過代碼進(jìn)行設(shè)置
/**
* 加載任意圓角圖片
*
* @param context
* @param picUrl
* @param simpleDraweeView
* @param topLeft
* @param topRight
* @param bottomLeft
* @param bottomRight
*/
public static void loadImage(Context context, String picUrl, final SimpleDraweeView simpleDraweeView, int topLeft, int topRight, int bottomLeft, int bottomRight) {
Uri fileUri = Uri.parse(picUrl);
RoundingParams params = RoundingParams.fromCornersRadii(
DensityUtils.dip2px(context, topLeft),
DensityUtils.dip2px(context, topRight),
DensityUtils.dip2px(context, bottomLeft),
DensityUtils.dip2px(context, bottomRight));
GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(context.getResources());
if (params != null) {
builder.setRoundingParams(params);
}
GenericDraweeHierarchy hierarchy = builder
.setFadeDuration(300)
.setPlaceholderImage(cn.com.nggirl.commons.R.drawable.works_list_default_img)
.setFailureImage(cn.com.nggirl.commons.R.drawable.works_list_default_img)
.setRetryImage(cn.com.nggirl.commons.R.drawable.works_list_default_img)
.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP)
.build();
final ImageRequest requestBuilder = ImageRequestBuilder.newBuilderWithSource(fileUri)
.setProgressiveRenderingEnabled(true)
.build();
final DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(requestBuilder)
.setAutoPlayAnimations(true)
.setTapToRetryEnabled(true)
.build();
simpleDraweeView.setHierarchy(hierarchy);
simpleDraweeView.setController(controller);
}
從上面的圓角設(shè)置可以看出來其中的一些屬性都是可以通過代碼進(jìn)行設(shè)置的。
fresco:roundAsCircle="true"http://顯示圓形圖片
高斯模糊
/**
* 以高斯模糊顯示啰劲。
*
* @param draweeView View梁沧。
* @param url url.
* @param iterations 迭代次數(shù),越大越魔化蝇裤。
* @param blurRadius 模糊圖半徑廷支,必須大于0,越大越模糊栓辜。
*/
public static void loadImage(String url, SimpleDraweeView draweeView, int iterations, int blurRadius) {
try {
Uri uri = Uri.parse(url);
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setPostprocessor(new IterativeBoxBlurPostProcessor(iterations, blurRadius))// iterations, blurRadius
.build();
AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
.setOldController(draweeView.getController())
.setImageRequest(request)
.build();
draweeView.setController(controller);
} catch (Exception e) {
e.printStackTrace();
}
}
加載 GIF 圖
/**
* 加載 GIF 圖
* 注意一定要導(dǎo)入正確的包
*
* @param url
* @param mSimpleDraweeView
*/
public static void loadImageGif(String url, SimpleDraweeView mSimpleDraweeView) {
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(Uri.parse(url))
.setAutoPlayAnimations(true)
.build();
mSimpleDraweeView.setController(controller);
}
還有一些加載圖片的效果恋拍,比如圖片邊框、過度圖藕甩、加載失敗的圖芝囤、占位圖等等效果,這里就需要我們根據(jù)自己的需要來進(jìn)行組合處理辛萍。
如果需要直接加載 bitmap 圖或者其他的圖片源悯姊,請(qǐng)移步我的例子代碼中。
高級(jí)設(shè)置
我們來說一下高級(jí)設(shè)置贩毕。
這里高級(jí)設(shè)置是指對(duì)緩存路徑的設(shè)置和使用自己的網(wǎng)絡(luò)加載庫(kù)悯许。
設(shè)置緩存路徑
/**
* 用于高級(jí)的初始化方法
* 1、用于指定緩存的路徑
* 注意:指定緩存路徑時(shí)需要考慮在 Android6.0 以后的運(yùn)行時(shí)權(quán)限問題
* 在設(shè)置緩存路徑為 SDK 時(shí)辉阶,要進(jìn)行判斷手機(jī)是否有 SDK先壕,如果沒有則使用默認(rèn)初始化
*
*/
private void frescoInitWithCache() {
Fresco.initialize(this, ImagePipelineConfig.newBuilder(this)
.setMainDiskCacheConfig(DiskCacheConfig.newBuilder(this)
.setBaseDirectoryPath(new File(""))// 指定緩存路徑
.build())
.build());
}
設(shè)置使用 OKHttp 為網(wǎng)絡(luò)加載層
/**
* 2、用于網(wǎng)絡(luò)加載的核心庫(kù)
* 注意:Fresco 默認(rèn)使用 HttpURLConnection 作為網(wǎng)絡(luò)層
* 這里使用網(wǎng)絡(luò)層為 Okhttp谆甜,導(dǎo)包為 com.facebook.fresco:imagepipeline-okhttp**
*/
private void frescoInitWithNet() {
OkHttpClient okHttpClient = new OkHttpClient();
Fresco.initialize(this, OkHttpImagePipelineConfigFactory
.newBuilder(this, okHttpClient)
.setMainDiskCacheConfig(DiskCacheConfig
.newBuilder(this)
.setBaseDirectoryPath(new File(""))// 指定緩存路徑
.build())
.build());
}
使用自己的網(wǎng)絡(luò)加載器
/**
* 3垃僚、使用自定義的網(wǎng)絡(luò)庫(kù)
* 注意:在使用自己定義的網(wǎng)絡(luò)庫(kù)時(shí)官方推薦:
* 為了完全控制網(wǎng)絡(luò)層的行為,你可以自定義網(wǎng)絡(luò)層规辱。
* 繼承NetworkFetchProducer, 這個(gè)類包含了網(wǎng)絡(luò)通信谆棺。
* 你也可以選擇性地繼承FetchState, 這個(gè)類是請(qǐng)求時(shí)的數(shù)據(jù)結(jié)構(gòu)描述。
*/
private void frescoInitWithCustomerNet() {
Fresco.initialize(this, ImagePipelineConfig
.newBuilder(this)
.setNetworkFetcher(customerNetWork)// 這里傳入自定義的網(wǎng)絡(luò)層
.build());
}
結(jié)語(yǔ)
這里已經(jīng)包含了圖片的最基本和常用的場(chǎng)景罕袋,感興趣的同學(xué)可以看一下 Fresco 的源碼改淑。了解一下 Fresco 的實(shí)現(xiàn)原理,或者到 Fresco 的官方文檔查看需求浴讯。
這里我們的 Fresco 的使用就要告一段落了朵夏,如果有一些新的使用方式,我會(huì)在例子代碼中持續(xù)更新榆纽。如果帖子中有什么不對(duì)的地方仰猖,希望小伙伴們踴躍提出來捏肢,俺們一定虛心接受。技術(shù)水平有限饥侵,勿噴鸵赫。
最后感謝提供參考文檔作者,你們真心不容易啊爆捞。