<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] ### 在XML中使用Drawees Drawees 具有極大的可定制性。 下面的例子給出了可以配置的各種選項: ~~~xml <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" /> ~~~ ##### 必須設置layout_width和layout_height 如果沒有在XML中聲明這兩個屬性,將無法正確加載圖像。 ##### wrap_content *Drawees 不支持 `wrap_content` 屬性。* 所下載的圖像可能和占位圖尺寸不一致,如果設置出錯圖或者重試圖的話,這些圖的尺寸也可能和所下載的圖尺寸不一致。 如果大小不一致,圖像下載完之后,假設如果是`wrap_content`,View將會重新layout,改變大小和位置。這將會導致界面跳躍。 ##### 固定寬高比 只有希望顯示的固定寬高比時,可以使用`wrap_content`。 如果希望顯示的圖片保持一定寬高比例,如果 4:3,則在XML中: ~~~xml <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/my_image_view" android:layout_width="20dp" android:layout_height="wrap_content" <!-- other attributes --> ~~~ 然后在代碼中指定顯示比例: ~~~java mSimpleDraweeView.setAspectRatio(1.33f); ~~~ ### 在JAVA代碼中使用Drawees #### 設置或更改要顯示的圖片 ~~~ mSimpleDraweeView.setImageURI(uri); ~~~ 如果要更加復雜的配置,可使用[ControllerBuilder](#); #### 自定義顯示圖 一般情況下,在[XML設置顯示效果即可](#), 如果想更多定制化,可以這樣: 創建一個 builder 然后設置給 DraweeView: ~~~java 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,請不要多次調用`setHierarchy`,即使這個View是可回收的。創建 DraweeHierarchy 的較為耗時的一個過程,應該多次利用。 如果要改變所要顯示的圖片可使用`setController` 或者 `setImageURI`。 #### 修改 DraweeHierarchy DraweeHierarchy 的一些屬性可以在運行時改變。 要改變這些屬性,首先獲取一個引用: ~~~java GenericDraweeHierarchy hierarchy = mSimpleDraweeView.getHierarchy(); ~~~ ##### 修改占位圖 修改占位圖為資源id: ~~~java hierarchy.setPlaceholderImage(R.drawable.placeholderId); ~~~ 或者修改為一個 [Drawable](http://developer.android.com/reference/android/graphics/drawable/Drawable.html): ~~~java Drawable drawable; // 創建一個drawable hierarchy.setPlaceholderImage(drawable); ~~~ ##### 修改顯示的圖像 修改[縮放類型](#): ~~~java hierarchy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE); ~~~ 當然,如果修改為 `focusCrop,` 需要指定一個居中點: ~~~java hierarchy.setActualImageFocusPoint(point); ~~~ 或者設置一個color filter: ~~~java ColorFilter filter; // 創建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: 除了圓角顯示方式(原來為圓角的不能修改為圓圈,反之亦然),其他圓角相關的呈現參數, [具體參見這里](#) 是可以動態修改的。 如下: 獲取DraweeHierarchy的圓角顯示參數,修改圓角半徑為10。 ~~~java RoundingParams roundingParams = hierarchy.getRoundingParams(); roundingParams.setCornersRadius(10); hierarchy.setRoundingParams(roundingParams); ~~~ ### Drawee的各種效果配置 ### 內容導航 - [定義](#) - [設置要加載的圖片](#) - [占位圖](#) - [加載失敗時的占位圖](#) - [點擊重新加載](#) - [顯示一個進度條](#) - [Backgrounds](#) - [Overlays](#) - [Pressed State Overlay](#) ### 定義 本頁說明如何設置實現不同的圖片呈現效果。 除了要加載的圖片,其他各個設置都可以在xml中指定。在xml中指定的時候,可以是 `drawable/`下的資源,也可以顏色。 在Java 代碼中也可以指定。如果需要 [通過程序設定](#) 的話會接觸到這個類: GenericDraweeHierarchyBuilder 通過代碼設置是,設置的值可以是資源id,也可以是 Drawable 的子類。 創建完 GenericDraweeHierarchy 之后,也可以通過該類的相關方法,重新設置一些效果。 大多數的用戶呈現不同效果的drawables都是可以[縮放的](#). ### 設置要加載的圖 除了需要加載的圖片是真正必須的,其他的都是可選的。如前所述,圖片可以來自多個地方。 所需加載的圖片實際是DraweeController的一個屬性,而不是 DraweeHierarchy 的屬性。 可使用`setImageURI`方法或者通過設置 DraweeController 來進行設置。 對于要加載的圖片,除了可以設置縮放類型外,DraweeHierarchy 還公開出一些其他方法用來控制顯示效果: - focus point (居中焦點, 用于 focusCrop 縮放模式) - color filter 默認的縮放類型是: `centerCrop` ### 占位圖(Placeholder) 在調用`setController` 或者 `setImageURI` 之后,占位圖開始顯示,直到圖片加載完成。 對于漸進式格式的JPEG圖片,占位圖會顯示直到滿足已加載的圖片解析度到達設定值。 XML 中屬性值: `placeholderImage` Hierarchy builder中的方法: `setPlaceholderImage` Hierarchy method: `setPlaceholderImage` 默認值: a transparent [ColorDrawable](http://developer.android.com/reference/android/graphics/drawable/ColorDrawable.html) 默認縮放類型: `centerInside` ### 設置加載失敗占位圖 如果URI是無效的,或者下載過程中網絡不可用,將會導致加載失敗。當加載圖片出錯時,你可以設置一個出錯提示圖片。 XML 中屬性值: `failureImage` Hierarchy builder中的方法: `setFailureImage` 默認值: The placeholder image 默認縮放類型: `centerInside` ### 點擊重新加載圖 在加載失敗時,可以設置點擊重新加載。這時提供一個圖片,加載失敗時,會顯示這個圖片(而不是失敗提示圖片),提示用戶點擊重試。 在[ControllerBuilder](#) 中如下設置: ~~~ .setTapToRetryEnabled(true) ~~~ 加載失敗時,image pipeline 會重試四次;如果還是加載失敗,則顯示加載失敗提示圖片。 XML 中屬性值: `retryImage` Hierarchy builder中的方法: `setRetryImage` 默認值: The placeholder image 默認縮放類型: `centerInside` ### 顯示一個進度條 設置一個進度條圖片,提示用戶正在加載。目前,進度條僅僅是提示正在loading,和加載進度無關。 XML 中屬性值: `progressBarImage` Hierarchy builder中的方法: `setProgressBarImage` 默認值: None 默認縮放類型: `centerInside` ### 背景 背景圖會最先繪制,在XML中只可以指定一個背景圖,但是在JAVA代碼中,可以指定多個背景圖。 當指定一個背景圖列表的時候,列表中的第一項會被首先繪制,繪制在最下層,然后依次往上繪制。 背景圖片不支持縮放類型,會被強制到`Drawee`尺寸大小。 XML 中屬性值: `backgroundImage` Hierarchy builder中的方法: `setBackground,``setBackgrounds` 默認值: None 默認縮放類型: N/A ### 設置疊加圖(Overlay) 疊加圖會最后被繪制。 和背景圖一樣,XML中只可以指定一個,如果想指定多個,可以通過JAVA代碼實現。 當指定的疊加圖是一個列表的時候,列表第一個元素會被先繪制,最后一個元素最后被繪制到最上層。 同樣的,不支持各種縮放類型。 XML 中屬性值: `overlayImage` Hierarchy builder中的方法: `setOverlay,``setOverlays` 默認值: None 默認縮放類型: N/A ### 設置按壓狀態下的疊加圖 同樣不支持縮放,用戶按壓DraweeView時呈現。 XML 中屬性值: `pressedStateOverlayImage` Hierarchy builder中的方法: `setPressedStateOverlay` 默認值: None 默認縮放類型: N/A ### 縮放 對于 Drawee 的[各種效果配置](#),其中一些是支持縮放類型的。 #### 可用的縮放類型 <table><thead><tr><th>類型</th> <th>描述</th></tr></thead><tbody><tr><td>center</td> <td>居中,無縮放</td></tr><tr><td>centerCrop</td> <td>保持寬高比縮小或放大,使得兩邊都大于或等于顯示邊界。居中顯示。</td></tr><tr><td><a class="internal" href="#focusCrop">focusCrop</a></td> <td>同centerCrop, 但居中點不是中點,而是指定的某個點</td></tr><tr><td>centerInside</td> <td>使兩邊都在顯示邊界內,居中顯示。<br/>如果圖尺寸大于顯示邊界,則保持長寬比縮小圖片。</td></tr><tr><td>fitCenter</td> <td>保持寬高比,縮小或者放大,使得圖片完全顯示在顯示邊界內。居中顯示</td></tr><tr><td>fitStart</td> <td>同上。但不居中,和顯示邊界左上對齊</td></tr><tr><td>fitEnd</td> <td>同fitCenter, 但不居中,和顯示邊界右下對齊</td></tr><tr><td>fitXY</td> <td>不保存寬高比,填充滿顯示邊界</td></tr><tr><td><a class="internal" href="#none">none</a></td> <td>如要使用tile mode顯示, 需要設置為none</td></tr></tbody></table> 這些縮放類型和Android [ImageView](http://developer.android.com/reference/android/widget/ImageView.ScaleType.html) 支持的縮放類型幾乎一樣. 唯一不支持的縮放類型是`matrix.` Fresco 提供了`focusCrop` 作為補充。通常這個縮放效果更佳。 #### focusCrop `centerCrop`縮放模式會保持長寬比,縮放圖片,填充滿顯示邊界,居中顯示。這個縮放模式在通常情況下很有用。 但是對于人臉等圖片時,一味地居中顯示,這個模式可能會裁剪掉一些有用的信息。 以人臉圖片為例,借助一些類庫,我們可以識別出人臉所在位置。如果可以設置以人臉位置居中裁剪顯示,那么效果會好很多。 Fresco的focusCrop縮放模式正是為此而設計。只要提供一個居中聚焦點,顯示時就會**盡量**以此點為中心。 居中點是以相對方式給出的,比如(0.5f, 0.5f)就是居中顯示,(0f, 0f)就是左上對齊顯示。 如果要使用此縮放模式,首先指定縮放模式。在XML: ~~~xml fresco:actualImageScaleType="focusCrop" ~~~ 在Java代碼中 ~~~java PointF focusPoint; // your app populates the focus point mSimpleDraweeView .getHierarchy() .setActualImageFocusPoint(focusPoint); ~~~ #### none 如果你要使用tile mode進行顯示,那么需要將scale type 設置為none. ### 圓角和圓圈 Drawee 輕松支持圓角顯示,并且顯示圓角時,并不復制和修改Bitmap對象,那樣太耗費內存。 #### 圓角 圓角實際有2中呈現方式: 1. 圓圈 - 設置`roundAsCircle`為true 1. 圓角 - 設置`roundedCornerRadius` 設置圓角時,支持4個角不同的半徑。XML中無法配置,但可在Java代碼中配置。 #### 設置圓角 可使用以下兩種方式: 1. 默認使用一個shader繪制圓角,但是僅僅占位圖所要顯示的圖有圓角效果。失敗示意圖和重下載示意圖無圓角效果。 1. 疊加一個`solid color`來繪制圓角。但是背景需要固定成指定的顏色。在XML中指定 `roundWithOverlayColor`, 或者通過調用`setOverlayColor`來完成此設定。 #### XML中配置 `SimpleDraweeView` 支持如下幾種圓角配置: ~~~xml <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 用來繪制圓角效果。 ~~~java RoundingParams roundingParams = RoundingParams.fromCornersRadius(7f); roundingParams.setOverlayColor(R.color.green); // 或用 fromCornersRadii 以及 asCircle 方法 genericDraweeHierarchyBuilder .setRoundingParams(roundingParams); ~~~ 你也可以在運行時,改變圓角效果 ~~~java RoundingParams roundingParams = mSimpleDraweeView.getHierarchy().getRoundingParams(); roundingParams.setBorder(R.color.red, 1.0); roundingParams.setRoundAsCircle(true); mSimpleDraweeView.getHierarchy().setRoundingParams(roundingParams); ~~~ > 在運行時,不能改變呈現方式: 原本是圓角,不能改為圓圈。 ### 使用ControllerBuilder `SimpleDraweeView` 有兩個方法可以設置所要加載顯示圖片,簡單的方法就是`setImageURI`。 如果你需要對加載顯示的圖片做更多的控制和定制,那就需要用到 DraweeController,本頁說明如何使用。 #### DraweeController 首先,創建一個DraweeController, 然后傳遞圖片加載請求給 PipelineDraweeControllerBuilder 隨后,你可以控制controller的其他選項了: ~~~java ControllerListener listener = new BaseControllerListener() {...} ? DraweeController controller = Fresco.newDraweeControllerBuilder() .setUri(uri) .setTapToRetryEnabled(true) .setOldController(mSimpleDraweeView.getController()) .setControllerListener(listener) .build(); ? mSimpleDraweeView.setController(controller); ~~~ 在指定一個新的controller的時候,使用`setOldController`,這可節省不必要的內存分配。 #### 自定義圖片加載請求 在更進一步的用法中,你需要給Image pipeline 發送一個ImageRequest。下面是一個圖片加載后,使用后處理器(postprocessor) 進行圖片后處理的例子. ~~~java Uri uri; Postprocessor myPostprocessor = new Postprocessor() { ... } ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) .setPostprocessor(myPostprocessor) .build(); ? DraweeController controller = Fresco.newDraweeControllerBuilder() .setImageRequest(request) .setOldController(mSimpleDraweeView.getController()) // 其他設置 .build(); ~~~ ### 漸進式JPEG圖 *注意: 本頁提及的API僅是初步設計,后續可能變動* Fresco 支持漸進式的網絡JPEG圖。在開始加載之后,圖會從模糊到清晰漸漸呈現。 你可以設置一個清晰度標準,在未達到這個清晰度之前,會一直顯示占位圖。 漸進式JPEG圖僅僅支持網絡圖。 ##### 初始化 [配置Image pipeline時](#) 需要傳遞一個 ProgressiveJpegConfig 的實例。 這個實例需要完成兩個事情:1. 返回下一個需要解碼的掃描次數2. 確定多少個掃描次數之后的圖片才能開始顯示。 下面的實例中,為了實現節省CPU,并不是每個掃描都進行解碼。 注意: - 每次解碼完之后,調用`getNextScanNumberToDecode`, 等待掃描值大于返回值,才有可能進行解碼。 假設,隨著下載的進行,下載完的掃描序列如下: `1, 4, 5, 10`。那么: 1. 首次調用`getNextScanNumberToDecode`返回為2, 因為初始時,解碼的掃描數為0。 1. 那么1將不會解碼,下載完成4個掃描時,解碼一次。下個解碼為掃描數為6 1. 5不會解碼,10才會解碼 ~~~java 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(); ~~~ 除了自己實現ProgressiveJpegConfig, 也可以直接使用 SimpleProgressiveJpegConfig ##### At Request Time 目前,我們必須顯式地在加載時,允許漸進式JPEG圖片加載。 ~~~java Uri uri; ImageRequest request = ImageRequestBuilder .newBuilderWithSource(uri) .setProgressiveRenderingEnabled(true) .build(); PipelineDraweeController controller = Fresco.newControllerBuilder() .setImageRequest(requests) .setOldController(mSimpleDraweeView.getController()) .build(); ? mSimpleDraweeView.setController(controller); ~~~ 我們希望在后續的版本中,在`setImageURI`方法中可以直接支持漸進式圖片加載。 ### 動畫圖(gif) Fresco 支持GIF和WebP 格式圖片;支持WebP 格式的動畫圖也支持(包括擴展WebP 格式),支持2.3及其以后那些沒有原生WebP支持的系統。 #### 設置動畫圖自動播放 如果你希望圖片下載完之后自動播放,同時,當View從屏幕移除時,停止播放,只需要在[image request](#) 中簡單設置,如下: ~~~java Uri uri; ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) .setAutoPlayAnimation(true) . // other setters .build(); ? DraweeController controller = Fresco.newDraweeControllerBuilder() .setImageRequest(request) . // other setters .build(); mSimpleDraweeView.setController(controller); ~~~ #### 手動控制動畫圖播放 也許,你希望在圖片加載完之后,手動控制動畫的播放,那么這樣做: ~~~java ControllerListener controllerListener = new BaseControllerListener() { @Override public void onFinalImageSet( String id, @Nullable ImageInfo imageInfo, @Nullable Animatable anim) { if (anim != null) { // 根據業務邏輯,在合適的時機播放動畫。 } }; ? Uri uri; PipelineDraweeController controller = Fresco.newControllerBuilder() .setControllerListener(controllerListener) .setUri(uri); // other setters .build(); mSimpleDraweeView.setController(controller); ~~~ 另外,controller提供對[Animatable](http://developer.android.com/reference/android/graphics/drawable/Animatable.html) 的訪問。 如果有可用動畫的話,可對動畫進行靈活的控制: ~~~java Animatable animation = mSimpleDraweeView.getController().getAnimatable(); if (animation != null) { // 開始播放 animation.start(); // 一段時間之后,根據業務邏輯,停止播放 animation.stop(); } ~~~ ### 多圖請求及圖片復用 多圖請求需 [自定義ImageRequest](#). #### 先顯示低分辨率的圖,然后是高分辨率的圖 如果你要顯示一張高分辨率的圖,但是這張圖下載比較耗時。你可以在下載前,先提供一張很快能下載完的小縮略圖。這比一直顯示占位圖,用戶體驗會好很多。 這時,你可以設置兩個圖片的URI,一個是低分辨率的縮略圖,一個是高分辨率的圖。 ~~~java 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完之后再顯示。 ~~~java Uri uri; ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) .setLocalThumbnailPreviewsEnabled(true) .build(); ? PipelineDraweeController controller = Fresco.newControllerBuilder() .setImageRequest(request) .setOldController(mSimpleDraweeView.getController()) .build(); mSimpleDraweeView.setController(controller); ~~~ #### 本地圖片復用 大部分的時候,一個圖片可能會對應有多個URI,比如: - 拍照上傳。本地圖片較大,上傳的圖片較小。上傳完成之后的圖片,有一個url,如果要加載這個url,可直接加載本地圖片。 - 本地已經有600x600尺寸的大圖了,需要顯示100x100的小圖 對于一個URI,image pipeline 會依次檢查內存,磁盤,如果沒有從網絡下載。 而對于一個圖片的多個URI,image pipeline 會先檢查他們是否在內存中。如果沒有任何一個是在內存中的,會檢查是否在本地存儲中。如果也沒有,才會執行網絡下載。 但凡有任何一個檢查發現在內存或者在本地存儲中,都會進行復用。列表順序就是要顯示的圖片的優先順序。 使用時,創建一個image request 列表,然后傳給ControllerBuilder: ~~~java 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`實現事件的監聽。 _在監聽事件回調時,無法修改圖片,如果需要修改圖片,可使用[后處理器(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` 都會被觸發。前者在成功時,后者在失敗時。 如果允許呈現[漸進式JPEG](#),同時圖片也是漸進式圖片,`onIntermediateImageSet`會在每個掃描被解碼后回調。具體圖片的那個掃描會被解碼,參見[漸進式JPEG圖](#) ### 縮放和旋轉圖片 使用這個功能需要直接[創建 image request](#)。 ### 縮放圖片 #### 什么時候該修改圖片尺寸 一般地,當所要顯示的圖片和顯示區域大小不一致時,會按以下方式進行處理。 1. 從服務器下載小一些的圖片 1. 顯示時縮放圖片 1. 調整圖片尺寸大小 對于一個圖片,如果服務器支持不同尺寸的縮略圖,那么每次下載都選擇尺寸最匹配的圖片,這個不僅節省數據流量也節約本地儲存和CPU。 如果服務器不支持,或者處理本地圖片的話,第二個選擇是[使用縮放類型](#)。縮放是用Androi內置的功能使圖像和顯示邊界相符。在4.0之后,支持硬件加速。這在大部分情況下是最快,同時也是最高效的顯示一張和顯示邊界大小相符的圖片的方式。首先指定`layout_width`和`layout_width`為指定值,然后指定[縮放類型](#) 但當所要顯示的圖片比顯示區域大許多的時候,不推薦這樣做,縮放過程會導致大量的內存消耗。 這時,需要改變圖片尺寸。 #### 修改圖片尺寸 調整大小并不是修改原來的文件,而是在解碼之前,在native內存中修改。 這個縮放方法,比Android內置的縮放范圍更大。Android相機生成的照片一般尺寸都很大,需要調整大小之后才能被顯示。 目前,僅僅支持JPEG格式的圖片,同時,大部分的Android系統相機圖片都是JPEG的。 如果要修改圖片尺寸,創建`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); ~~~ ### 自動旋轉 如果看到的圖片是側著的,用戶是難受的。許多設備會在JPEG文件的metadata中記錄下照片的方向。如果你想圖片呈現的方向和設備屏幕的方向一致,你可以簡單地這樣做到: ~~~java ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) .setAutoRotateEnabled(true) .build(); // as above ~~~ ### 修改圖片 有時,我們想對從服務器下載,或者本地的圖片做些修改,比如在某個坐標統一加個網格什么的。這時使用后處理器(Postprocessor)便可達到目的。 ##### 例子: 給圖片加個網格: ~~~java 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內存中。 在開始一個圖片顯示時,即使是反復顯示同一個圖片,在每次進行顯示時,都需要指定后處理器。 對于同一個圖片,每次顯示,可以使用不同的后處理器。 ##### Repeated Postprocessors 如果想對同一個圖片進行多次后處理,那么繼承 BaseRepeatedPostprocessor 即可。該類有一個`update`方法,需要執行后處理時,調用該方法即可。 下面的例子展示了在運行時,后處理改變圖片網格的顏色: ~~~java 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`,但是這個后處理器是狀態相關了。 ### 圖片請求 如果你需要的`ImageRequest`僅僅是一個URI,那么`ImageRequest.fromURI`就足夠了,在[多圖請求及圖片復用](#)中,有這樣的用法。 否則,你需要`ImageRequestBuilder`來做更多的事情。 ~~~java 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(); ~~~ ##### ImageRequest 的屬性和成員 - `uri` - 唯一的必選的成員. 參考 [支持的URIs](#) - `autoRotateEnabled` - 是否支持[自動旋轉](#). - `progressiveEnabled` - 是否支持[漸進式加載](#). - `postprocessor` - [后處理器(postprocess)](#). - `resizeOptions` - 圖片縮放選項,用前請先閱讀[縮放和旋轉](#). ##### 最低請求級別 Image pipeline 加載圖片時有一套明確的[請求流程](#) 1. 檢查內存緩存,有如,立刻返回。這個操作是實時的。 1. 檢查未解碼的圖片緩存,如有,解碼并返回。 1. 檢查磁盤緩存,如果有加載,解碼,返回。 1. 下載或者加載本地文件。調整大小和旋轉(如有),解碼并返回。對于網絡圖來說,這一套流程下來是最耗時的。 `setLowestPermittedRequestLevel`允許設置一個最低請求級別,請求級別和上面對應地有以下幾個取值: - `BITMAP_MEMORY_CACHE` - `ENCODED_MEMORY_CACHE` - `DISK_CACHE` - `FULL_FETCH` 如果你需要立即取到一個圖片,或者在相對比較短時間內取到圖片,否則就不顯示的情況下,這非常有用。 ### 自定義View #### DraweeHolders 總有一些時候,`DraweeViews`是滿足不了需求的,在展示圖片的時候,我們還需要展示一些其他的內容,或者支持一些其他的操作。在同一個View里,我們可能會想顯示一張或者多張圖。 在自定義View中,Fresco 提供了兩個類來負責圖片的展現: - `DraweeHolder` 單圖情況下用。 - `MultiDraweeHolder` 多圖情況下用。 #### 自定義View需要完成的事情 Android 呈現View對象,只有View對象才能得到一些系統事件的通知。`DraweeViews`處理這些事件通知,高效地管理內存。使用`DraweeHolder`時,你需要自己實現這幾個方法。 ##### 處理 attach/detach 事件 **如果沒按照以下步驟實現的話,很可能會引起內存泄露** 當圖片不再在View上顯示時,比如滑動時View滑動到屏幕外,或者不再繪制,圖片就不應該再存在在內存中。Drawees 監聽這些事情,并負責釋放內存。當圖片又需要顯示時,重新加載。 這些在`DraweeView`中是自動的,但是在自定義View中,需要我們自己去操作,如下: ~~~java DraweeHolder mDraweeHolder; ? @Override public void onDetachedFromWindow() { super.onDetachedToWindow(); mDraweeHolder.onDetach(); } ? @Override public void onStartTemporaryDetach() { super.onStartTemporaryDetach(); mDraweeHolder.onDetach(); } ? @Override public void onAttachedToWindow() { super.onAttachedToWindow(); mDraweeHolder.onAttach(); } ? @Override public void onFinishTemporaryDetach() { super.onFinishTemporaryDetach(); mDraweeHolder.onAttach(); } ~~~ ##### 處理觸摸事件 如果你啟用了[點擊重新加載](#),在自定義View中,需要這樣: ~~~java @Override public boolean onTouchEvent(MotionEvent event) { return mDraweeHolder.onTouchEvent(event) || super.onTouchEvent(event); } ~~~ ##### 自定義onDraw ~~~java Drawable drawable = mDraweeHolder.getHierarchy().getTopLevelDrawable(); drawable.setBounds(...); ~~~ 否則圖片將不會出現 - 不要向下轉換這個Drawable - 不要變換這個Drawable ##### 其他應該做的 - 重寫 `verifyDrawable:` ~~~java @Override protected boolean verifyDrawable(Drawable who) { if (who == mDraweeHolder.getHierarchy().getTopLevelDrawable()) { return true; } // 對其他Drawable的驗證邏輯 } ~~~ - 確保`invalidateDrawable` 處理了圖片占用的那塊區域。 #### 創建 DraweeHolder 這同樣需要非常小心和細致 ##### 構造函數 我們推薦如下實現構造函數: - 重寫3個構造函數 - 在每個構造函數中調用同等簽名的父類構造函數,和一個私有的`init`方法。 - 在`init`方法中執行初始化操作。 即,不要在構造函數中用`this`來調用另外一個構造。 這樣可以保證,不管調用哪個構造,都可以正確地執行初始化流程。然后在`init`方法中創建holder。 ##### 創建 Holder 如果有可能,只在View創建時,創建Drawees。創建DraweeHierarchy開銷較大,最好只做一次。 ~~~java class CustomView extends View { DraweeHolder<GenericDraweeHierarchy> mDraweeHolder; ? // constructors following above pattern ? private void init() { GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources()); .set... .set... .build(); mDraweeHolder = DraweeHolder.create(hierarchy, context); } } ~~~ ##### 設置要顯示的圖片 使用[controller builder](#)創建DraweeController,然后調用holder的`setController`方法,而不是設置給自定義View。 ~~~java DraweeController controller = Fresco.newControllerBuilder() .setUri(uri) .setOldController(mDraweeHolder.getController()) .build(); mDraweeHolder.setController(controller); ~~~ #### MultiDraweeHolder 和`DraweeHolder`相比,`MultiDraweeHolder`有 `add`, `remove`, `clear`等方法可以操作Drawees。如下: ~~~java MultiDraweeHolder<GenericDraweeHierarchy> mMultiDraweeHolder; ? private void init() { GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources()); .set... .build(); mMultiDraweeHolder = new MultiDraweeHolder<GenericDraweeHierarchy>(); mMultiDraweeHolder.add(new DraweeHolder<GenericDraweeHierarchy>(hierarchy, context)); // repeat for more hierarchies } ~~~ 同樣,也需要處理系統事件,設置聲音等等,就想處理單個`DraweeHolder`那樣。 ### 一些陷阱 ##### 不要向下轉換 不要試圖把Fresco返回的一些對象進行向下轉化,這也許會帶來一些對象操作上的便利,但是也許在后續的版本中,你會遇到一些因為向下轉換特性丟失導致的難以處理的問題。 ##### 不要使用getTopLevelDrawable `DraweeHierarchy.getTopLevelDrawable()`**僅僅** 應該在DraweeViews中用,除了定義View中,其他應用代碼建議連碰都不要碰這個。 在自定義View中,也千萬不要將返回值向下轉換,也許下個版本,我們會更改這個返回值類型。 ##### 不要復用 DraweeHierarchies 永遠不要吧`DraweeHierarchy` 通過 `DraweeView.setHierarchy` 設置給不同的View。DraweeHierarchy是由一系列Drawable組成的。在Android中, Drawable不能被多個View共享。 ##### 不要在多個DraweeHierarchy中使用同一個Drawable 原因同上。當時可以使用不同的資源ID。Android實際會創建不同的Drawable。 ##### 不要直接給 `DraweeView` 設置圖片。 目前 `DraweeView` 直接繼承于ImageView,因此它有 `setImageBitmap`,`setImageDrawable` 等方法。 如果利用這些方法,直接設置一個圖片。內部的`DraweeHierarchy`就會丟失,也就無法取到imagepipeline 的任何圖像了。 ##### 使用DraweeView時,請不要使用任何ImageView的屬性 在后續的版本中,DraweeView會直接從View派生。任何屬于ImageView但是不屬于View的方法都會被移除。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看