前言
對fresco框架源碼的閱讀學習,學習優秀的編碼方式和較爲實用常見設計模式,該篇講得比較淺,主要是理清三個主要類的之間的關係。
本篇目錄
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
提供給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);