fresco的源碼學習自我總結

前言

  對fresco框架源碼的閱讀學習,學習優秀的編碼方式和較爲實用常見設計模式,該篇講得比較淺,主要是理清三個主要類的之間的關係。

本篇目錄
  • fresco框架的MVC模式
  • fresco的DraweeView、DraweeHierarchy、DraweeController的簡單介紹
  • fresco的DraweeView、DraweeHierarchy、DraweeController的建立順序

 fresco 框架的 MVC模式
java

View - DraweeView 設計模式

Model - DraweeHierarchy數組

Controleer - DraweeControllerapp

 

其中Hierarchy和Controller保存在DraweeHolder中,須要從Holder中get方式獲得。目的是將Hierarchy和Controller封裝在一塊兒,解耦出來,若是要自定義DraweeView只須要在類中新添DraweeHolder類就能夠比較方便地擁有Hierarchy和Controller了。

  DraweeView
  DraweeHolder
    |  
    |-- DraweeHierarchy
    |
    |-- DraweeController框架

----------------------------------------------------------------------------------------------------------------------------------------ide

 fresco的DraweeView、DraweeHierarchy、DraweeController的簡單介紹 學習

 V-DraweeView 
                  
                  |--------- DraweeView
                  |      
                  |(extends)
        |--------- GenericDraweeView
        |      
        |(extends)
    SimpleDraweeView

(越接近開發者的層越爲簡單,方便理解,較爲複雜的邏輯在頂層父類實現。)

SimpleDraweeViewView動畫

  控件對外的表層的model,只提供簡單setImageURL方法,做用爲修改顯示圖片URLui

public void setImageURI(Uri uri)

public void setImageURI(@Nullable String uriString)

public void setImageURI(@Nullable String uriString, @Nullable Object callerContext)

public void setImageURI(Uri uri, @Nullable Object callerContext)

 

GenericDraweeView編碼

  其方法只有一個,在其構造方法中被調用,做用爲初始化DraweeHierarchy

protected void inflateHierarchy(Context context, @Nullable AttributeSet attrs)

 

DraweeView

   0.11.0版本依然是繼承自ImageView,看網上說後面會直接繼承自View,負責圖片的顯示,其中重要的一個方法:getTopLevelDrawable()用來得到Hierarchy儲存的頂層圖片進行顯示。

  @Nullable public Drawable getTopLevelDrawable() {
    return mDraweeHolder.getTopLevelDrawable();
  }
DraweeHolder: public Drawable getTopLevelDrawable() {
    return mHierarchy == null ? null : mHierarchy.getTopLevelDrawable();
  }

 

   M-DraweeHierarchy 

                  |--------- DraweeHierarchy
                  |      
                  |(extends)
        |--------- SettableDraweeHierarchy
        |      
        |(implements)
   GenericDraweeHierarchy

 SettableDraweeHierarchy、DraweeHierarchy皆爲接口類,GenericDraweeHierarchy實現他們的方法。

 

DraweeHierarchy

  只有一個簡單卻重要的方法,做用得到在Hierarchy中的FadeDrawable中儲存的頂層圖片進行顯示,FaceDrawable是個圖片數組,裏面包含所須要的全部圖片。

  Drawable getTopLevelDrawable();

 

SettableDraweeHierarchy

  裏面的接口方法均爲提供給Controller調用來控制圖像,在GenericDraweeHierarchy中實現

  void reset();
  void setImage(Drawable drawable, float progress, boolean immediate);
  void setProgress(float progress, boolean immediate);
  void setFailure(Throwable throwable);
  void setRetry(Throwable throwable);
  void setControllerOverlay(Drawable drawable);

 

GenericDraweeHierarchy

  GenericDraweeHierarchy實現了父類的接口,提供給Controller調用來控制圖片的顯示。

  其中要三個主要的Drawable對象:

  FadeDrawable,它存儲了須要到的圖片資源,包括顯示圖片、加載圖片、失敗時顯示的圖片等等。繼承自ArrayDrawable,層級類圖片集合。會選擇圖片數組中的最後一張進行顯示。

  RootDrawable(mTopLevelDrawable)即儲存了FadeDrawable的頂層圖片,爲要即將要顯示的圖片

  ForwardingDrawable(mActualImageWrapper) 即儲存了目標圖片

  其中FadeDrawable類中的主要方法有:

  public void setTransitionDuration(int durationMs);\\設置隱藏/顯示圖層漸變更畫時間(默認爲300ms)
  public void fadeInLayer(int index);\\顯示指定圖層
  public void fadeOutLayer(int index);\\隱藏指定圖層
  public void fadeInAllLayers();\\顯示全部圖層
  public void fadeOutAllLayers();\\隱藏全部圖層
  public void fadeToLayer(int index);\\顯示指定圖層同時隱藏其餘圖層
  public void fadeUpToLayer(int index);\\隱藏數組下標<=index的圖層

  以上方法 會修改 boolean[] mIsLayerOn布爾數組,來判斷是否顯示圖片。

 

   C-DraweeController 

 

  •   在初始化框架時會建立一個PipelineDraweeControllerBuilderSupplier,並保存在SimpleDraweeView和Fresco兩個類中,以靜態變量的方式,因此Controller的建立有兩個入口。
  •   建立Controller時經過初始化的sDraweeControllerBuilderSupplier得到一個SimpleDraweeControllerBuilder,再用建造器模式建立出一個DraweeController。
  •   事實上DraweeController的建立是在AbstractDraweeControllerBuilder調用實現了的build()方法,buildr()方法又調用了PipelineDraweeControllerBuilder得到一個PipelineDraweeController,返回builder()後轉換成AbstractDraweeController,在最外層的調用又轉換成DraweeController。(java的多態)

  提供給SimpleDraweeView建立Controller的方法只有簡單的幾個,即在SimpleDraweeControllerBuilder中的接口方法。

 SimpleDraweeControllerBuilder

  SimpleDraweeControllerBuilder setCallerContext(Object callerContext);
  SimpleDraweeControllerBuilder setUri(Uri uri);
  SimpleDraweeControllerBuilder setUri(@Nullable String uriString);
  SimpleDraweeControllerBuilder setOldController(@Nullable DraweeController oldController);
  DraweeController build();

  而在代碼中動態建立Controller再設置給SimpleDraweeView則有更多能夠設置的屬性方法,這些方法保存在AbstractDraweeController中,建立方式在下面會寫到。

 

fresco的DraweeView、DraweeHierarchy、DraweeController的建立順序

初始化順序爲:

1.DraweeView

其他都爲DraweeView對象中的類,因此先有DraweeView

 

2.DraweeHolder (在DraweeView的init()方法中建立 保存在DraweeView中) 

DraweeView:
DraweeHolder.create(null, context)
DraweeHolder: public static <DH extends DraweeHierarchy> DraweeHolder<DH> create(
      @Nullable DH hierarchy,
      Context context) {
    DraweeHolder<DH> holder = new DraweeHolder<DH>(hierarchy);
    holder.registerWithContext(context);
    return holder;
  }

 

3.DraweeHierarchy (在GenericDraweeView的inflateHierarchy()方法中建立 保存在DraweeHolder和DraweeController中)

GenericDraweeView:
 protected void inflateHierarchy(Context context, @Nullable AttributeSet attrs) {
    GenericDraweeHierarchyBuilder builder =
        GenericDraweeHierarchyInflater.inflateBuilder(context, attrs);
    setAspectRatio(builder.getDesiredAspectRatio());
    setHierarchy(builder.build());
  }

 

 4.DraweeController

並不預先建立,而是在使用到控件的時候動態建立,有兩種建立途徑,但兩種都是經過拿到DraweeControllerBuilderSupplier 用建造器模式去建立Controller

  ①.調用SimpleDraweeView中的setImageURL(),源碼中已寫好建立Controller的代碼,只設置圖片URL

例:(SimpleDraweeView中的源碼)
    public void setImageURI(Uri uri, @Nullable Object callerContext) {
      DraweeController controller = mSimpleDraweeControllerBuilder
          .setCallerContext(callerContext)
          .setUri(uri)
          .setOldController(getController())
          .build();
      setController(controller);
    }

 

  ②.在代碼中使用到的時候動態建立,能自定義更多關於圖片的屬性方法,如須要監聽一張GIF圖片的播放結束事件,就須要本身在代碼中動態建立(高版本已經把對gif的支持單獨出去,這裏只作一個例子)

例:(本身項目代碼)
        SimpleDraweeView view = (SimpleDraweeView) contentView.findViewById(R.id.exp_first_gif);

        ControllerListener listener = new BaseControllerListener() {
            @Override
            public void onFinalImageSet(String id, @Nullable Object imageInfo, @Nullable Animatable animatable) {
                super.onFinalImageSet(id, imageInfo, animatable);
                valueAnimator.start();
            }

        };

        Uri uri = Uri.parse("res://com.--------/" + R.drawable.gif_exp_one);
        DraweeController draweeController =
                Fresco.newDraweeControllerBuilder()
                        .setControllerListener(listener)
                        .setUri(uri)
                        .setAutoPlayAnimations(true) // 設置加載圖片完成後是否直接進行播放
                        .build();
        view.setController(draweeController);
相關文章
相關標籤/搜索