天天看點

Android【Fresco】 使用的詳解(二)

上次說了Fresco的基本使用方式

這次來說說,Fresco的更多使用

Android【Fresco】 使用的詳解(二)

設定縮放類型

實際圖檔,占位圖,重試圖和失敗圖都可以在 xml 中進行設定,用 fresco:actualImageScaleType 這樣的屬性。你也可以使用 GenericDraweeHierarchyBuilder 類在代碼中進行設定。

其中可用的縮放類型如下

center  居中,無縮放。 
centerCrop  保持寬高比縮小或放大,使得兩邊都大于或等于顯示邊界,且寬或高契合顯示邊界。居中顯示。 
focusCrop  同centerCrop, 但居中點不是中點,而是指定的某個點。 
centerInside  縮放圖檔使兩邊都在顯示邊界内,居中顯示。和 fitCenter 不同,不會對圖檔進行放大。
如果圖尺寸大于顯示邊界,則保持長寬比縮小圖檔。 
fitCenter  保持寬高比,縮小或者放大,使得圖檔完全顯示在顯示邊界内,且寬或高契合顯示邊界。居中顯示。 
fitStart  同上。但不居中,和顯示邊界左上對齊。 
fitEnd  同fitCenter, 但不居中,和顯示邊界右下對齊。 
fitXY  不儲存寬高比,填充滿顯示邊界。 
none  如要使用tile mode顯示, 需要設定為``
one 

           

其中focusCrop,隻要提供一個居中聚焦點,顯示時就會盡量以此點為中心。

居中點是以相對方式給出的,比如 (0f, 0f) 是左上對齊顯示,(1f, 1f) 是右下角對齊。相對坐标使得居中點位置和具體尺寸無關,這是非常實用的。

(0.5f, 0.5f) 的居中點位置和縮放類型 centerCrop 是等價的。

如果要使用此縮放模式,首先在 XML 中指定縮放模式:

在Java代碼中,給你的圖檔指定居中點:

PointF focusPoint;
// your app populates the focus point
mSimpleDraweeView
    .getHierarchy()
    .setActualImageFocusPoint(focusPoint);
           

設定圖檔圓角,圓圈

圓角

圓角實際有2種呈現方式:

1.圓圈 - 設定roundAsCircle為true

2.圓角 - 設定roundedCornerRadius

設定圓角

可使用以下兩種方式:

1.預設使用一個 shader 繪制圓角,但是僅僅占位圖和所要顯示的圖有圓角效果。失敗示意圖和重下載下傳示意圖無圓角效果,且這種圓角方式不支援動畫。

2.疊加一個solid color來繪制圓角。但是背景需要固定成指定的顔色。 在XML中指定 roundWithOverlayColor, 或者通過調用setOverlayColor來完成此設定。

XML中配置

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"
           

代碼中配置

在建立 DraweeHierarchy 時,可以給 GenericDraweeHierarchyBuilder 指定一個RoundingParams 用來繪制圓角效果。

RoundingParams roundingParams = RoundingParams.fromCornersRadius(f);
roundingParams.setOverlayColor(R.color.green);
// 或用 fromCornersRadii 以及 asCircle 方法
genericDraweeHierarchyBuilder
    .setRoundingParams(roundingParams);
           

你也可以在運作時,改變圓角效果

RoundingParams roundingParams = 
    mSimpleDraweeView.getHierarchy().getRoundingParams();
roundingParams.setBorder(R.color.red, );
roundingParams.setRoundAsCircle(true);
mSimpleDraweeView.getHierarchy().setRoundingParams(roundingParams);
           

注意

當使用BITMAP_ONLY(預設)模式時的限制:

• 并非所有的圖檔分支部分都可以實作圓角,目前隻有占位圖檔和實際圖檔可以實作圓角,我們正在努力為背景圖檔實作圓角功能。

• 隻有BitmapDrawable 和 ColorDrawable類的圖檔可以實作圓角。我們目前不支援包括NinePatchDrawable和 ShapeDrawable在内的其他類型圖檔。(無論他們是在XML或是程式中聲明的)

• 動畫不能被圓角。

• 由于Android的BitmapShader的限制,當一個圖檔不能覆寫全部的View的時候,邊緣部分會被重複顯示,而非留白。對這種情況可以使用不同的縮放類型(比如centerCrop)來保證圖檔覆寫了全部的View。

OVERLAY_COLOR模式沒有上述限制,但由于這個模式使用在圖檔上覆寫一個純色圖層的方式來模拟圓角效果,是以隻有在圖示背景是靜止的并且與圖層同色的情況下才能獲得較好的效果。

GIF動圖加載

Fresco 支援 GIF 和 WebP 格式的動畫圖檔。對于 WebP 格式的動畫圖的支援包括擴充的 WebP 格式,即使 Android 2.3及其以後那些沒有原生 WebP 支援的系統。

設定動畫圖自動播放

如果你希望圖檔下載下傳完之後自動播放,同時,當View從螢幕移除時,停止播放,隻需要在 image request 中簡單設定,如下:

Uri uri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setUri(uri)
    .setAutoPlayAnimations(true)
    . // other setters
    .build();
mSimpleDraweeView.setController(controller);
           

手動控制動畫圖播放

也許你希望在代碼中直接控制動畫的播放。這種情況下,你需要監聽圖檔是否加載完畢,然後才能控制動畫的播放:

ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {
    @Override
    public void onFinalImageSet(
        String id,
        @Nullable ImageInfo imageInfo,
        @Nullable Animatable anim) {
    if (anim != null) {
      // app-specific logic to enable animation starting
      anim.start();
    }
};

Uri uri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setUri(uri)
    .setControllerListener(controllerListener)
    // other setters
    .build();
mSimpleDraweeView.setController(controller);


另外,controller提供對Animatable 的通路。

如果有可用動畫的話,可對動畫進行靈活的控制:

Animatable animation = mSimpleDraweeView.getController().getAnimatable();
if (animation != null) {
  // 開始播放
  animation.start();
  // 一段時間之後,根據業務邏輯,停止播放
  animation.stop();
}

           

多圖請求及圖檔複用

多圖請求需 自定義ImageRequest.

先顯示低分辨率的圖,然後是高分辨率的圖

假設你要顯示一張高分辨率的圖,但是這張圖下載下傳比較耗時。與其一直顯示占位圖,你可能想要先下載下傳一個較小的縮略圖。

這時,你可以設定兩個圖檔的URI,一個是低分辨率的縮略圖,一個是高分辨率的圖。

Uri lowResUri, highResUri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setLowResImageRequest(ImageRequest.fromUri(lowResUri))
    .setImageRequest(ImageRequest.fromUri(highResUri))
    .setOldController(mSimpleDraweeView.getController())
    .build();
mSimpleDraweeView.setController(controller);
           

縮略圖預覽

本功能僅支援本地URI,并且是JPEG圖檔格式

如果本地JPEG圖,有EXIF的縮略圖,image pipeline 可以立刻傳回它作為一個縮略圖。Drawee 會先顯示縮略圖,完整的清晰大圖在 decode 完之後再顯示。

Uri uri;
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
    .setLocalThumbnailPreviewsEnabled(true)
    .build();

DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setImageRequest(request)
    .setOldController(mSimpleDraweeView.getController())
    .build();
mSimpleDraweeView.setController(controller);
           

加載最先可用的圖檔

大部分時候,一張圖檔隻有一個 URI。加載它,然後工作完成~

但是假設同一張圖檔有多個 URI 的情況。比如,你可能上傳過一張拍攝的照片。原始圖檔太大而不能上傳,是以圖檔首先經過了壓縮。在這種情況下,首先嘗試擷取本地壓縮後的圖檔 URI,如果失敗的話,嘗試擷取本地原始圖檔 URI,如果還是失敗的話,嘗試擷取上傳到網絡的圖檔 URI。直接下載下傳我們本地可能已經有了的圖檔不是一件光彩的事。

Image pipeline 會首先從記憶體中搜尋圖檔,然後是磁盤緩存,再然後是網絡或其他來源。對于多張圖檔,不是一張一張按上面的過程去做,而是 pipeline 先檢查所有圖檔是否在記憶體。隻有沒在記憶體被搜尋到的才會尋找磁盤緩存。還沒有被搜尋到的,才會進行一個外部請求。

使用時,建立一個image request 數組,然後傳給 ControllerBuilder :

Uri uri1, uri2;
ImageRequest request = ImageRequest.fromUri(uri1);
ImageRequest request2 = ImageRequest.fromUri(uri2);
ImageRequest[] requests = { request1, request2 };

DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setFirstAvailableImageRequests(requests)
    .setOldController(mSimpleDraweeView.getController())
    .build();
mSimpleDraweeView.setController(controller);
           

這些請求中隻有一個會被展示。第一個被發現的,無論是在記憶體,磁盤或者網絡,都會是被傳回的那個。pipeline 認為數組中請求的順序即為優先順序。

清除緩存

清除緩存中的一條url

ImagePipeline現有函數可以删除緩存中的一條url。

ImagePipeline imagePipeline = Fresco.getImagePipeline();
Uri uri;
imagePipeline.evictFromMemoryCache(uri);
imagePipeline.evictFromDiskCache(uri);

// combines above two lines
imagePipeline.evictFromCache(uri);

           

如同上面一樣,evictFromDiskCache(Uri)假定你使用的是預設的CacheKeyFactory。如果你自定義,請使用evictFromDiskCache(ImageRequest)。

清除緩存

ImagePipeline imagePipeline = Fresco.getImagePipeline();
imagePipeline.clearMemoryCaches();
imagePipeline.clearDiskCaches();

// combines above two lines
imagePipeline.clearCaches();

           

更多詳情請參考官網:http://www.fresco-cn.org/