Fresco源碼解析,fresco源碼

來源:互聯網
上載者:User

Fresco源碼解析,fresco源碼

Fresco是一個MVC模型,由三大組件構成,它們的對應關係如下所示:

  • M -> DraweeHierarchy
  • V -> DraweeView
  • C -> DraweeController

M 所對應的 DraweeHierarchy 是一個有階層的資料結構,DraweeView 用來顯示位於 DraweeHierarchy 最頂層的映像(top level drawable),DraweeController 則用來控制 DraweeHierarchy 的頂層映像是哪一個。

 o FadeDrawable (top level drawable) | +--o ScaleTypeDrawable |  | |  +--o BitmapDrawable | +--o ScaleTypeDrawable    |    +--o BitmapDrawable

三者的互動關係很簡單,DraweeView 把獲得的 Event 轉寄給 Controller,然後 Controller 根據 Event 來決定是否需要顯示和隱藏 (包括動畫)映像,而這些映像都儲存在 Hierarchy 中,最後 DraweeView 繪製時直接通過 getTopLevelDrawable 就可以擷取需要顯示的映像。

需要注意的是,雖然現在最新的代碼中,DraweeView 還是繼承自 ImageView,但是以後會直接繼承 View,所以我們用 DraweeView 時,盡量不要使用 ImageView 的API,例如 setImageXxxsetScaleType,注釋裡也寫得很清楚。

Although ImageView is subclassed instead of subclassing View directly, this class does not support ImageView’s setImageXxx, setScaleType and similar methods. Extending ImageView is a short term solution in order to inherit some of its implementation (padding calculations, etc.). This class is likely to be converted to extend View directly in the future, so avoid using ImageView’s methods and properties (T5856175).

由關係圖可以看出,DraweeView 中並沒有 DraweeHierarchyDraweeController 類型的成員變數,而只有一個 DrawHolder 類型的 mDrawHolder

public class DraweeHolder<DH extends DraweeHierarchy> implements VisibilityCallback {  // other properties  private DH mHierarchy;  private DraweeController mController = null;  // methods}

DraweeHolder 儲存了 mHierarchymController,FB 為什麼要這麼設計呢?注釋裡也寫得很清楚:

Drawee users, should, as a rule, use DraweeView or its subclasses. There are situations where custom views are required, however, and this class is for those circumstances.

稍微解釋一下,這是一個解耦的設計,當我們不想使用 DraweeView,通過 ViewHolder 照樣可以使用其他兩個組件。比方說,自訂一個View,然後像 DraweeView 那樣,在 View 中添加一個 DrawHolder 的成員變數。

再來看 DraweeView 的代碼:

public class DraweeView<DH extends DraweeHierarchy> extends ImageView {  // other methods and properties  /** Sets the hierarchy. */  public void setHierarchy(DH hierarchy) {    mDraweeHolder.setHierarchy(hierarchy);    super.setImageDrawable(mDraweeHolder.getTopLevelDrawable());  }  /** Sets the controller. */  public void setController(@Nullable DraweeController draweeController) {    mDraweeHolder.setController(draweeController);    super.setImageDrawable(mDraweeHolder.getTopLevelDrawable());  }}

每次為 DraweeView 設定 hierarchycontroller 時,會同時通過 super.setImageDrawable(mDraweeHolder.getTopLevelDrawable()) 更新需要顯示的映像。

/** * Gets the top-level drawable if hierarchy is set, null otherwise. */public Drawable getTopLevelDrawable() {  return mHierarchy == null ? null : mHierarchy.getTopLevelDrawable();}

DraweeHierarchy 只定義了一個方法 - getTopLevelDrawable

public interface DraweeHierarchy {  /**   * Returns the top level drawable in the corresponding hierarchy. Hierarchy should always have   * the same instance of its top level drawable.   * @return top level drawable   */  public Drawable getTopLevelDrawable();}

DraweeController 也是一個介面,暴露了設定 hierarchy 和接收 Event 的方法。

  • void setHierarchy(@Nullable DraweeHierarchy hierarchy)
  • public boolean onTouchEvent(MotionEvent event)
/** * Interface that represents a Drawee controller used by a DraweeView. * <p> The view forwards events to the controller. The controller controls * its hierarchy based on those events. */public interface DraweeController {  /** Gets the hierarchy. */  @Nullable  public DraweeHierarchy getHierarchy();  /** Sets a new hierarchy. */  void setHierarchy(@Nullable DraweeHierarchy hierarchy);  /**   * Called when the view containing the hierarchy is attached to a window   * (either temporarily or permanently).   */  public void onAttach();  /**   * Called when the view containing the hierarchy is detached from a window   * (either temporarily or permanently).   */  public void onDetach();  /**   * Called when the view containing the hierarchy receives a touch event.   * @return true if the event was handled by the controller, false otherwise   */  public boolean onTouchEvent(MotionEvent event);  /**   * For an animated image, returns an Animatable that lets clients control the animation.   * @return animatable, or null if the image is not animated or not loaded yet   */  public Animatable getAnimatable();}

通過以上分析可以看出,DraweeControllerDraweeHierarchyDraweeView 三者共同構成了 Fresco 的三駕馬車,下面的博文會各個擊破,分析他們的實現原理和代碼層次。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.