Drawees 具有極大的可定制性。
下面的例子給出了可以配置的各種選項:
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="20dp"
android:layout_height="20dp"
fresco:fadeDuration="300"
fresco:actualImageScaleType="focusCrop"
fresco:placeholderImage="@color/wait_color"
fresco:placeholderImageScaleType="fitCenter"
fresco:failureImage="@drawable/error"
fresco:failureImageScaleType="centerInside"
fresco:retryImage="@drawable/retrying"
fresco:retryImageScaleType="centerCrop"
fresco:progressBarImage="@drawable/progress_bar"
fresco:progressBarImageScaleType="centerInside"
fresco:progressBarAutoRotateInterval="1000"
fresco:backgroundImage="@color/blue"
fresco:overlayImage="@drawable/watermark"
fresco:pressedStateOverlayImage="@color/red"
fresco:roundAsCircle="false"
fresco:roundedCornerRadius="1dp"
fresco:roundTopLeft="true"
fresco:roundTopRight="false"
fresco:roundBottomLeft="false"
fresco:roundBottomRight="true"
fresco:roundWithOverlayColor="@color/corner_color"
fresco:roundingBorderWidth="2dp"
fresco:roundingBorderColor="@color/border_color"
/>
如果沒有在XML中聲明這兩個屬性,將無法正確加載圖像。
Drawees 不支持 wrap_content
屬性。
所下載的圖像可能和占位圖尺寸不一致,如果設(shè)置出錯圖或者重試圖的話,這些圖的尺寸也可能和所下載的圖尺寸不一致。
如果大小不一致,圖像下載完之后,假設(shè)如果是wrap_content
,View將會重新layout,改變大小和位置。這將會導致界面跳躍。
只有希望顯示的固定寬高比時,可以使用wrap_content
。
如果希望顯示的圖片保持一定寬高比例,如果 4:3,則在XML中:
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="20dp"
android:layout_height="wrap_content"
<!-- other attributes -->
然后在代碼中指定顯示比例:
mSimpleDraweeView.setAspectRatio(1.33f);
mSimpleDraweeView.setImageURI(uri);
如果要更加復雜的配置,可使用ControllerBuilder;
一般情況下,在XML設(shè)置顯示效果即可, 如果想更多定制化,可以這樣:
創(chuàng)建一個 builder 然后設(shè)置給 DraweeView:
List<Drawable> backgroundsList;
List<Drawable> overlaysList;
GenericDraweeHierarchyBuilder builder =
new GenericDraweeHierarchyBuilder(getResources());
GenericDraweeHierarchy hierarchy = builder
.setFadeDuration(300)
.setPlaceholderImage(new MyCustomDrawable())
.setBackgrounds(backgroundList)
.setOverlays(overlaysList)
.build();
mSimpleDraweeView.setHierarchy(hierarchy);
對于同一個View,請不要多次調(diào)用setHierarchy
,即使這個View是可回收的。創(chuàng)建 DraweeHierarchy 的較為耗時的一個過程,應該多次利用。
如果要改變所要顯示的圖片可使用setController
或者 setImageURI
。
DraweeHierarchy 的一些屬性可以在運行時改變。
要改變這些屬性,首先獲取一個引用:
GenericDraweeHierarchy hierarchy = mSimpleDraweeView.getHierarchy();
修改占位圖為資源id:
hierarchy.setPlaceholderImage(R.drawable.placeholderId);
或者修改為一個 Drawable:
Drawable drawable;
// 創(chuàng)建一個drawable
hierarchy.setPlaceholderImage(drawable);
修改縮放類型:
hierarchy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE);
當然,如果修改為 focusCrop,
需要指定一個居中點:
hierarchy.setActualImageFocusPoint(point);
或者設(shè)置一個color filter:
ColorFilter filter;
// 創(chuàng)建filter
hierarchy.setActualImageColorFilter(filter);
All of the rounding related params, except the rounding method, can be modified. You get a RoundingParams
object from the hierarchy, modify it, and set it back again:
除了圓角顯示方式(原來為圓角的不能修改為圓圈,反之亦然),其他圓角相關(guān)的呈現(xiàn)參數(shù), 具體參見這里 是可以動態(tài)修改的。
如下: 獲取DraweeHierarchy的圓角顯示參數(shù),修改圓角半徑為10。
RoundingParams roundingParams = hierarchy.getRoundingParams();
roundingParams.setCornersRadius(10);
hierarchy.setRoundingParams(roundingParams);
本頁說明如何設(shè)置實現(xiàn)不同的圖片呈現(xiàn)效果。
除了要加載的圖片,其他各個設(shè)置都可以在xml中指定。在xml中指定的時候,可以是 drawable/
下的資源,也可以顏色。
在Java 代碼中也可以指定。如果需要 通過程序設(shè)定 的話會接觸到這個類: GenericDraweeHierarchyBuilder
通過代碼設(shè)置是,設(shè)置的值可以是資源id,也可以是 Drawable 的子類。
創(chuàng)建完 GenericDraweeHierarchy 之后,也可以通過該類的相關(guān)方法,重新設(shè)置一些效果。
大多數(shù)的用戶呈現(xiàn)不同效果的drawables都是可以縮放的.
除了需要加載的圖片是真正必須的,其他的都是可選的。如前所述,圖片可以來自多個地方。
所需加載的圖片實際是DraweeController的一個屬性,而不是 DraweeHierarchy 的屬性。
可使用setImageURI
方法或者通過設(shè)置 DraweeController 來進行設(shè)置。
對于要加載的圖片,除了可以設(shè)置縮放類型外,DraweeHierarchy 還公開出一些其他方法用來控制顯示效果:
默認的縮放類型是: centerCrop
在調(diào)用setController
或者 setImageURI
之后,占位圖開始顯示,直到圖片加載完成。
對于漸進式格式的JPEG圖片,占位圖會顯示直到滿足已加載的圖片解析度到達設(shè)定值。
XML 中屬性值: placeholderImage
Hierarchy builder中的方法: setPlaceholderImage
Hierarchy method: setPlaceholderImage
默認值: a transparent ColorDrawable
默認縮放類型: centerInside
如果URI是無效的,或者下載過程中網(wǎng)絡(luò)不可用,將會導致加載失敗。當加載圖片出錯時,你可以設(shè)置一個出錯提示圖片。
XML 中屬性值: failureImage
Hierarchy builder中的方法: setFailureImage
默認值: The placeholder image
默認縮放類型: centerInside
在加載失敗時,可以設(shè)置點擊重新加載。這時提供一個圖片,加載失敗時,會顯示這個圖片(而不是失敗提示圖片),提示用戶點擊重試。
在ControllerBuilder 中如下設(shè)置:
.setTapToRetryEnabled(true)
加載失敗時,image pipeline 會重試四次;如果還是加載失敗,則顯示加載失敗提示圖片。
XML 中屬性值: retryImage
Hierarchy builder中的方法: setRetryImage
默認值: The placeholder image
默認縮放類型: centerInside
設(shè)置一個進度條圖片,提示用戶正在加載。目前,進度條僅僅是提示正在loading,和加載進度無關(guān)。
XML 中屬性值: progressBarImage
Hierarchy builder中的方法: setProgressBarImage
默認值: None
默認縮放類型: centerInside
背景圖會最先繪制,在XML中只可以指定一個背景圖,但是在JAVA代碼中,可以指定多個背景圖。
當指定一個背景圖列表的時候,列表中的第一項會被首先繪制,繪制在最下層,然后依次往上繪制。
背景圖片不支持縮放類型,會被強制到Drawee
尺寸大小。
XML 中屬性值: backgroundImage
Hierarchy builder中的方法: setBackground,``setBackgrounds
默認值: None
默認縮放類型: N/A
疊加圖會最后被繪制。
和背景圖一樣,XML中只可以指定一個,如果想指定多個,可以通過JAVA代碼實現(xiàn)。
當指定的疊加圖是一個列表的時候,列表第一個元素會被先繪制,最后一個元素最后被繪制到最上層。
同樣的,不支持各種縮放類型。
XML 中屬性值: overlayImage
Hierarchy builder中的方法: setOverlay,``setOverlays
默認值: None
默認縮放類型: N/A
同樣不支持縮放,用戶按壓DraweeView時呈現(xiàn)。
XML 中屬性值: pressedStateOverlayImage
Hierarchy builder中的方法: setPressedStateOverlay
默認值: None
默認縮放類型: N/A
對于 Drawee 的各種效果配置,其中一些是支持縮放類型的。
類型 | 描述 |
---|---|
center | 居中,無縮放 |
centerCrop | 保持寬高比縮小或放大,使得兩邊都大于或等于顯示邊界。居中顯示。 |
focusCrop | 同centerCrop, 但居中點不是中點,而是指定的某個點 |
centerInside | 使兩邊都在顯示邊界內(nèi),居中顯示。 如果圖尺寸大于顯示邊界,則保持長寬比縮小圖片。 |
fitCenter | 保持寬高比,縮小或者放大,使得圖片完全顯示在顯示邊界內(nèi)。居中顯示 |
fitStart | 同上。但不居中,和顯示邊界左上對齊 |
fitEnd | 同fitCenter, 但不居中,和顯示邊界右下對齊 |
fitXY | 不保存寬高比,填充滿顯示邊界 |
none | 如要使用tile mode顯示, 需要設(shè)置為none |
這些縮放類型和Android ImageView 支持的縮放類型幾乎一樣.
唯一不支持的縮放類型是matrix.
Fresco 提供了focusCrop
作為補充。通常這個縮放效果更佳。
centerCrop
縮放模式會保持長寬比,縮放圖片,填充滿顯示邊界,居中顯示。這個縮放模式在通常情況下很有用。
但是對于人臉等圖片時,一味地居中顯示,這個模式可能會裁剪掉一些有用的信息。
以人臉圖片為例,借助一些類庫,我們可以識別出人臉所在位置。如果可以設(shè)置以人臉位置居中裁剪顯示,那么效果會好很多。
Fresco的focusCrop縮放模式正是為此而設(shè)計。只要提供一個居中聚焦點,顯示時就會盡量以此點為中心。
居中點是以相對方式給出的,比如(0.5f, 0.5f)就是居中顯示,(0f, 0f)就是左上對齊顯示。
如果要使用此縮放模式,首先指定縮放模式。在XML:
fresco:actualImageScaleType="focusCrop"
在Java代碼中
PointF focusPoint;
// your app populates the focus point
mSimpleDraweeView
.getHierarchy()
.setActualImageFocusPoint(focusPoint);
如果你要使用tile mode進行顯示,那么需要將scale type 設(shè)置為none.
Drawee 輕松支持圓角顯示,并且顯示圓角時,并不復制和修改Bitmap對象,那樣太耗費內(nèi)存。
圓角實際有2中呈現(xiàn)方式:
roundAsCircle
為trueroundedCornerRadius
設(shè)置圓角時,支持4個角不同的半徑。XML中無法配置,但可在Java代碼中配置。
可使用以下兩種方式:
solid color
來繪制圓角。但是背景需要固定成指定的顏色。在XML中指定 roundWithOverlayColor
, 或者通過調(diào)用setOverlayColor
來完成此設(shè)定。SimpleDraweeView
支持如下幾種圓角配置:
<com.facebook.drawee.view.SimpleDraweeView
...
fresco:roundedCornerRadius="5dp"
fresco:roundBottomLeft="false"
fresco:roundBottomRight="false"
fresco:roundWithOverlayColor="@color/blue"
fresco:roundingBorderWidth="1dp"
fresco:roundingBorderColor="@color/red"
在創(chuàng)建 DraweeHierarchy 時,可以給GenericDraweeHierarchyBuilder
指定一個 RoundingParams 用來繪制圓角效果。
RoundingParams roundingParams = RoundingParams.fromCornersRadius(7f);
roundingParams.setOverlayColor(R.color.green);
// 或用 fromCornersRadii 以及 asCircle 方法
genericDraweeHierarchyBuilder
.setRoundingParams(roundingParams);
你也可以在運行時,改變圓角效果
RoundingParams roundingParams =
mSimpleDraweeView.getHierarchy().getRoundingParams();
roundingParams.setBorder(R.color.red, 1.0);
roundingParams.setRoundAsCircle(true);
mSimpleDraweeView.getHierarchy().setRoundingParams(roundingParams);
在運行時,不能改變呈現(xiàn)方式: 原本是圓角,不能改為圓圈。
SimpleDraweeView
有兩個方法可以設(shè)置所要加載顯示圖片,簡單的方法就是setImageURI
。
如果你需要對加載顯示的圖片做更多的控制和定制,那就需要用到 DraweeController,本頁說明如何使用。
首先,創(chuàng)建一個DraweeController, 然后傳遞圖片加載請求給 PipelineDraweeControllerBuilder
隨后,你可以控制controller的其他選項了:
ControllerListener listener = new BaseControllerListener() {...}
?
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setTapToRetryEnabled(true)
.setOldController(mSimpleDraweeView.getController())
.setControllerListener(listener)
.build();
?
mSimpleDraweeView.setController(controller);
在指定一個新的controller的時候,使用setOldController
,這可節(jié)省不必要的內(nèi)存分配。
在更進一步的用法中,你需要給Image pipeline 發(fā)送一個ImageRequest。下面是一個圖片加載后,使用后處理器(postprocessor) 進行圖片后處理的例子.
Uri uri;
Postprocessor myPostprocessor = new Postprocessor() { ... }
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setPostprocessor(myPostprocessor)
.build();
?
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(mSimpleDraweeView.getController())
// 其他設(shè)置
.build();
注意: 本頁提及的API僅是初步設(shè)計,后續(xù)可能變動
Fresco 支持漸進式的網(wǎng)絡(luò)JPEG圖。在開始加載之后,圖會從模糊到清晰漸漸呈現(xiàn)。
你可以設(shè)置一個清晰度標準,在未達到這個清晰度之前,會一直顯示占位圖。
漸進式JPEG圖僅僅支持網(wǎng)絡(luò)圖。
配置Image pipeline時 需要傳遞一個 ProgressiveJpegConfig 的實例。
這個實例需要完成兩個事情:1. 返回下一個需要解碼的掃描次數(shù)2. 確定多少個掃描次數(shù)之后的圖片才能開始顯示。
下面的實例中,為了實現(xiàn)節(jié)省CPU,并不是每個掃描都進行解碼。
注意:
getNextScanNumberToDecode
, 等待掃描值大于返回值,才有可能進行解碼。假設(shè),隨著下載的進行,下載完的掃描序列如下: 1, 4, 5, 10
。那么:
getNextScanNumberToDecode
返回為2, 因為初始時,解碼的掃描數(shù)為0。ProgressiveJpegConfig pjpegConfig = new ProgressiveJpegConfig() {
@Override
public int getNextScanNumberToDecode(int scanNumber) {
return scanNumber + 2;
}
?
public QualityInfo getQualityInfo(int scanNumber) {
boolean isGoodEnough = (scanNumber >= 5);
return ImmutableQualityInfo.of(scanNumber, isGoodEnough, false);
}
}
?
ImagePipelineConfig config = ImagePipelineConfig.newBuilder()
.setProgressiveJpegConfig(pjpeg)
.build();
除了自己實現(xiàn)ProgressiveJpegConfig, 也可以直接使用 SimpleProgressiveJpegConfig
目前,我們必須顯式地在加載時,允許漸進式JPEG圖片加載。
Uri uri;
ImageRequest request = ImageRequestBuilder
.newBuilderWithSource(uri)
.setProgressiveRenderingEnabled(true)
.build();
PipelineDraweeController controller = Fresco.newControllerBuilder()
.setImageRequest(requests)
.setOldController(mSimpleDraweeView.getController())
.build();
?
mSimpleDraweeView.setController(controller);
我們希望在后續(xù)的版本中,在setImageURI
方法中可以直接支持漸進式圖片加載。
Fresco 支持GIF和WebP 格式圖片;支持WebP 格式的動畫圖也支持(包括擴展WebP 格式),支持2.3及其以后那些沒有原生WebP支持的系統(tǒng)。
如果你希望圖片下載完之后自動播放,同時,當View從屏幕移除時,停止播放,只需要在image request 中簡單設(shè)置,如下:
Uri uri;
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setAutoPlayAnimation(true)
. // other setters
.build();
?
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
. // other setters
.build();
mSimpleDraweeView.setController(controller);
也許,你希望在圖片加載完之后,手動控制動畫的播放,那么這樣做:
ControllerListener controllerListener = new BaseControllerListener() {
@Override
public void onFinalImageSet(
String id,
@Nullable ImageInfo imageInfo,
@Nullable Animatable anim) {
if (anim != null) {
// 根據(jù)業(yè)務(wù)邏輯,在合適的時機播放動畫。
}
};
?
Uri uri;
PipelineDraweeController controller = Fresco.newControllerBuilder()
.setControllerListener(controllerListener)
.setUri(uri);
// other setters
.build();
mSimpleDraweeView.setController(controller);
另外,controller提供對Animatable 的訪問。
如果有可用動畫的話,可對動畫進行靈活的控制:
Animatable animation = mSimpleDraweeView.getController().getAnimatable();
if (animation != null) {
// 開始播放
animation.start();
// 一段時間之后,根據(jù)業(yè)務(wù)邏輯,停止播放
animation.stop();
}
多圖請求需 自定義ImageRequest.
如果你要顯示一張高分辨率的圖,但是這張圖下載比較耗時。你可以在下載前,先提供一張很快能下載完的小縮略圖。這比一直顯示占位圖,用戶體驗會好很多。
這時,你可以設(shè)置兩個圖片的URI,一個是低分辨率的縮略圖,一個是高分辨率的圖。
Uri lowResUri, highResUri;
PipelineDraweeController controller = Fresco.newControllerBuilder()
.setLowResImageRequest(ImageRequest.fromUri(lowResUri))
.setImageRequest(ImageRequest.fromUri(highResUri))
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);
本功能僅支持本地URI,并且是JPEG圖片格式
如果本地JPEG圖,有EXIF的縮略圖,image pipeline 會立刻返回一個縮略圖。完整的清晰大圖,在decode完之后再顯示。
Uri uri;
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setLocalThumbnailPreviewsEnabled(true)
.build();
?
PipelineDraweeController controller = Fresco.newControllerBuilder()
.setImageRequest(request)
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);
大部分的時候,一個圖片可能會對應有多個URI,比如:
對于一個URI,image pipeline 會依次檢查內(nèi)存,磁盤,如果沒有從網(wǎng)絡(luò)下載。
而對于一個圖片的多個URI,image pipeline 會先檢查他們是否在內(nèi)存中。如果沒有任何一個是在內(nèi)存中的,會檢查是否在本地存儲中。如果也沒有,才會執(zhí)行網(wǎng)絡(luò)下載。
但凡有任何一個檢查發(fā)現(xiàn)在內(nèi)存或者在本地存儲中,都會進行復用。列表順序就是要顯示的圖片的優(yōu)先順序。
使用時,創(chuàng)建一個image request 列表,然后傳給ControllerBuilder:
Uri uri1, uri2;
ImageRequest request = ImageRequest.fromUri(uri1);
ImageRequest request2 = ImageRequest.fromUri(uri2);
ImageRequest[] requests = { request1, request2 };
?
PipelineDraweeController controller = Fresco.newControllerBuilder()
.setFirstAvailableImageRequests(requests)
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);
你也許想在圖片下載完成或者下載失敗之后,做一些其他事情。
圖片是后臺線程異步加載的,我們可以使用一個ControllerListener
實現(xiàn)事件的監(jiān)聽。
_在監(jiān)聽事件回調(diào)時,無法修改圖片,如果需要修改圖片,可使用后處理器(Postprocessor)
~~~ ControllerListener controllerListener = new BaseControllerListener() {
@Override
public void onFinalImageSet(
String id,
@Nullable ImageInfo imageInfo,
@Nullable Animatable anim) {
if (imageInfo == null) {
return;
}
QualityInfo qualityInfo = imageInfo.getQualityInfo();
FLog.d("Final image received! " +
"Size %d x %d",
"Quality level %d, good enough: %s, full quality: %s",
imageInfo.getWidth(),
imageInfo.getHeight(),
qualityInfo.getQuality(),
qualityInfo.isOfGoodEnoughQuality(),
qualityInfo.isOfFullQuality());
}
?
@Override
public void onIntermediateImageSet(String id, @Nullable ImageInfo imageInfo) {
FLog.d("Intermediate image received");
}
?
@Override
public void onFailure(String id, Throwable throwable) {
FLog.e(getClass(), throwable, "Error loading %s", id)
}
};
?
Uri uri;
DraweeController controller = Fresco.newControllerBuilder()
.setControllerListener(controllerListener)
.setUri(uri);
// other setters
.build();
mSimpleDraweeView.setController(controller);
對所有的圖片加載,`onFinalImageSet` 或者 `onFailure` 都會被觸發(fā)。前者在成功時,后者在失敗時。
如果允許呈現(xiàn)[漸進式JPEG](#),同時圖片也是漸進式圖片,`onIntermediateImageSet`會在每個掃描被解碼后回調(diào)。具體圖片的那個掃描會被解碼,參見[漸進式JPEG圖](#)
### 縮放和旋轉(zhuǎn)圖片
使用這個功能需要直接[創(chuàng)建 image request](#)。
### 縮放圖片
#### 什么時候該修改圖片尺寸
一般地,當所要顯示的圖片和顯示區(qū)域大小不一致時,會按以下方式進行處理。
1. 從服務(wù)器下載小一些的圖片
1. 顯示時縮放圖片
1. 調(diào)整圖片尺寸大小
對于一個圖片,如果服務(wù)器支持不同尺寸的縮略圖,那么每次下載都選擇尺寸最匹配的圖片,這個不僅節(jié)省數(shù)據(jù)流量也節(jié)約本地儲存和CPU。
如果服務(wù)器不支持,或者處理本地圖片的話,第二個選擇是[使用縮放類型](#)??s放是用Androi內(nèi)置的功能使圖像和顯示邊界相符。在4.0之后,支持硬件加速。這在大部分情況下是最快,同時也是最高效的顯示一張和顯示邊界大小相符的圖片的方式。首先指定`layout_width`和`layout_width`為指定值,然后指定[縮放類型](#)
但當所要顯示的圖片比顯示區(qū)域大許多的時候,不推薦這樣做,縮放過程會導致大量的內(nèi)存消耗。
這時,需要改變圖片尺寸。
#### 修改圖片尺寸
調(diào)整大小并不是修改原來的文件,而是在解碼之前,在native內(nèi)存中修改。
這個縮放方法,比Android內(nèi)置的縮放范圍更大。Android相機生成的照片一般尺寸都很大,需要調(diào)整大小之后才能被顯示。
目前,僅僅支持JPEG格式的圖片,同時,大部分的Android系統(tǒng)相機圖片都是JPEG的。
如果要修改圖片尺寸,創(chuàng)建`ImageRequest`時,提供一個 ResizeOptions:
~~~java
Uri uri = "file:///mnt/sdcard/MyApp/myfile.jpg";
int width = 50, height = 50;
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setResizeOptions(new ResizeOptions(width, height))
.build();
PipelineDraweeController controller = Fresco.newDraweeControllerBuilder()
.setOldController(mDraweeView.getController())
.setImageRequest(request)
.build();
mSimpleDraweeView.setController(controller);
如果看到的圖片是側(cè)著的,用戶是難受的。許多設(shè)備會在JPEG文件的metadata中記錄下照片的方向。如果你想圖片呈現(xiàn)的方向和設(shè)備屏幕的方向一致,你可以簡單地這樣做到:
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setAutoRotateEnabled(true)
.build();
// as above
有時,我們想對從服務(wù)器下載,或者本地的圖片做些修改,比如在某個坐標統(tǒng)一加個網(wǎng)格什么的。這時使用后處理器(Postprocessor)便可達到目的。
給圖片加個網(wǎng)格:
Uri uri;
Postprocessor redMeshPostprocessor = new Postprocessor() {
@Override
public String getName() {
return "redMeshPostprocessor";
}
?
@Override
public void process(Bitmap bitmap) {
for (int x = 0; x < bitmap.getWidth(); x+=2) {
for (int y = 0; y < bitmap.getHeight(); y+=2) {
bitmap.setPixel(x, y, Color.RED);
}
}
}
}
?
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setPostprocessor(redMeshPostprocessor)
.build();
?
PipelineDraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(mSimpleDraweeView.getOldController())
// other setters as you need
.build();
mSimpleDraweeView.setController(controller);
圖片在進入后處理器(postprocessor)的圖片是原圖的一個完整拷貝,原來的圖片不受修改的影響。在5.0以前的機器上,拷貝后的圖片也在native內(nèi)存中。
在開始一個圖片顯示時,即使是反復顯示同一個圖片,在每次進行顯示時,都需要指定后處理器。
對于同一個圖片,每次顯示,可以使用不同的后處理器。
如果想對同一個圖片進行多次后處理,那么繼承 BaseRepeatedPostprocessor 即可。該類有一個update
方法,需要執(zhí)行后處理時,調(diào)用該方法即可。
下面的例子展示了在運行時,后處理改變圖片網(wǎng)格的顏色:
public class MeshPostprocessor extends BaseRepeatedPostprocessor {
private int mColor = Color.TRANSPARENT;
?
public void setColor(int color) {
mColor = color;
update();
}
?
@Override
public String getName() {
return "meshPostprocessor";
}
?
@Override
public void process(Bitmap bitmap) {
for (int x = 0; x < bitmap.getWidth(); x+=2) {
for (int y = 0; y < bitmap.getHeight(); y+=2) {
bitmap.setPixel(x, y, mColor);
}
}
}
}
MeshPostprocessor meshPostprocessor = new MeshPostprocessor();
?
// setPostprocessor as in above example
?
// 改變顏色
meshPostprocessor.setColor(Color.RED);
meshPostprocessor.setColor(Color.BLUE);
每個image request, 仍舊只有一個Postprocessor
,但是這個后處理器是狀態(tài)相關(guān)了。
如果你需要的ImageRequest
僅僅是一個URI,那么ImageRequest.fromURI
就足夠了,在多圖請求及圖片復用中,有這樣的用法。
否則,你需要ImageRequestBuilder
來做更多的事情。
Uri uri;
?
ImageDecodeOptions decodeOptions = ImageDecodeOptions.newBuilder()
.setBackgroundColor(Color.GREEN)
.build();
?
ImageRequest request = ImageRequestBuilder
.newBuilderWithSource(uri)
.setAutoRotateEnabled(true)
.setLocalThumbnailPreviewsEnabled(true)
.setLowestPermittedRequestLevel(RequestLevel.FULL_FETCH)
.setProgressiveRenderingEnabled(false)
.setResizeOptions(new ResizeOptions(width, height))
.build();
uri
- 唯一的必選的成員. 參考 支持的URIsautoRotateEnabled
- 是否支持自動旋轉(zhuǎn).progressiveEnabled
- 是否支持漸進式加載.postprocessor
- 后處理器(postprocess).resizeOptions
- 圖片縮放選項,用前請先閱讀縮放和旋轉(zhuǎn).Image pipeline 加載圖片時有一套明確的請求流程
setLowestPermittedRequestLevel
允許設(shè)置一個最低請求級別,請求級別和上面對應地有以下幾個取值:
BITMAP_MEMORY_CACHE
ENCODED_MEMORY_CACHE
DISK_CACHE
FULL_FETCH
如果你需要立即取到一個圖片,或者在相對比較短時間內(nèi)取到圖片,否則就不顯示的情況下,這非常有用。
總有一些時候,DraweeViews
是滿足不了需求的,在展示圖片的時候,我們還需要展示一些其他的內(nèi)容,或者支持一些其他的操作。在同一個View里,我們可能會想顯示一張或者多張圖。
在自定義View中,F(xiàn)resco 提供了兩個類來負責圖片的展現(xiàn):
DraweeHolder
單圖情況下用。MultiDraweeHolder
多圖情況下用。
更多建議: