在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Android/ 自定義View
進度條
在JAVA代碼中使用Drawees
Drawee的各種效果配置
緩存
一些陷阱
關于在Android Studio中編譯
多圖請求及圖片復用
自定義網絡加載
支持的URIs
可關閉的引用
監(jiān)聽下載事件
修改圖片
引入Fresco
縮放
圓角和圓圈
配置Image Pipeline
縮放和旋轉圖片
(圖片請求)Image Requests
自定義View
使用ControllerBuilder
在XML中使用Drawees
開始使用 Fresco
關鍵概念
Image Pipeline介紹
漸進式JPEG圖
數據源和數據訂閱者
直接使用Image Pipeline
動畫圖(gif)
使用其他的Image Loader

自定義View

本教程內容來源于:http://fresco-cn.org
采用 知識共享 署名 4.0 國際 許可協議 進行許可

DraweeHolders

總有一些時候,DraweeViews是滿足不了需求的,在展示圖片的時候,我們還需要展示一些其他的內容,或者支持一些其他的操作。在同一個View里,我們可能會想顯示一張或者多張圖。

在自定義View中,Fresco 提供了兩個類來負責圖片的展現:

  • DraweeHolder 單圖情況下用。
  • MultiDraweeHolder 多圖情況下用。

自定義View需要完成的事情

Android 呈現View對象,只有View對象才能得到一些系統事件的通知。DraweeViews 處理這些事件通知,高效地管理內存。使用DraweeHolder時,你需要自己實現這幾個方法。

處理 attach/detach 事件

如果沒按照以下步驟實現的話,很可能會引起內存泄露

當圖片不再在View上顯示時,比如滑動時View滑動到屏幕外,或者不再繪制,圖片就不應該再存在在內存中。Drawees 監(jiān)聽這些事情,并負責釋放內存。當圖片又需要顯示時,重新加載。

這些在DraweeView中是自動的,但是在自定義View中,需要我們自己去操作,如下:

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中,需要這樣:

@Override
public boolean onTouchEvent(MotionEvent event) {
  return mDraweeHolder.onTouchEvent(event) || super.onTouchEvent(event);
}

自定義onDraw

Drawable drawable = mDraweeHolder.getHierarchy().getTopLevelDrawable();
drawable.setBounds(...);

否則圖片將不會出現

  • 不要向下轉換這個Drawable
  • 不要變換這個Drawable

其他應該做的

  • 重寫 verifyDrawable:
@Override
protected boolean verifyDrawable(Drawable who) {
  if (who == mDraweeHolder.getHierarchy().getTopLevelDrawable()) {
    return true;
  }
  // 對其他Drawable的驗證邏輯
}
  • 確保invalidateDrawable 處理了圖片占用的那塊區(qū)域。

創(chuàng)建 DraweeHolder

這同樣需要非常小心和細致

構造函數

我們推薦如下實現構造函數:

  • 重寫3個構造函數
  • 在每個構造函數中調用同等簽名的父類構造函數,和一個私有的init方法。
  • init方法中執(zhí)行初始化操作。

即,不要在構造函數中用this來調用另外一個構造。

這樣可以保證,不管調用哪個構造,都可以正確地執(zhí)行初始化流程。然后在init方法中創(chuàng)建holder。

創(chuàng)建 Holder

如果有可能,只在View創(chuàng)建時,創(chuàng)建Drawees。創(chuàng)建DraweeHierarchy開銷較大,最好只做一次。

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創(chuàng)建DraweeController,然后調用holder的setController方法,而不是設置給自定義View。

DraweeController controller = Fresco.newControllerBuilder()
    .setUri(uri)
    .setOldController(mDraweeHolder.getController())
    .build();
mDraweeHolder.setController(controller);

MultiDraweeHolder

DraweeHolder相比,MultiDraweeHolderadd, remove, clear 等方法可以操作Drawees。如下:

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那樣。