fresco框架的MVC模式
fresco的DraweeView、DraweeHierarchy、DraweeController的簡單介紹
fresco的DraweeView、DraweeHierarchy、DraweeController的創(chuàng)建順序
fresco 框架的 MVC模式
View - DraweeView
Model - DraweeHierarchy
Controleer - DraweeController
其中Hierarchy和Controller保存在DraweeHolder中,需要從Holder中get方式得到。目的是將Hierarchy和Controller封裝在一起,解耦出來,如果要自定義DraweeView只需要在類中新添DraweeHolder類就可以比較方便地擁有Hierarchy和Controller了。
DraweeView
DraweeHolder
|
|-- DraweeHierarchy
|
|-- DraweeController
----------------------------------------------------------------------------------------------------------------------------------------
fresco的DraweeView、DraweeHierarchy、DraweeController的簡單介紹
|--------- | |(extends)
|--------- | |(extends)
(越接近開發(fā)者的層越為簡單,方便理解,較為復雜的邏輯在頂層父類實現(xiàn)。)
SimpleDraweeViewView
控件對外的表層的model,只提供簡單setImageURL方法,作用為修改顯示圖片URL
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
其方法只有一個,在其構造方法中被調(diào)用,作用為初始化DraweeHierarchy
protected void inflateHierarchy(Context context, @Nullable AttributeSet attrs)
DraweeView
0.11.0版本依然是繼承自ImageView,看網(wǎng)上說后面會直接繼承自View,負責圖片的顯示,其中重要的一個方法:getTopLevelDrawable()用來獲得Hierarchy儲存的頂層圖片進行顯示。
@Nullable public Drawable getTopLevelDrawable() { return mDraweeHolder.getTopLevelDrawable(); }
DraweeHolder: public Drawable getTopLevelDrawable() { return mHierarchy == null ? null : mHierarchy.getTopLevelDrawable(); }
M-DraweeHierarchy
|--------- | |(extends)
|--------- | |(implements)
SettableDraweeHierarchy、DraweeHierarchy皆為接口類,GenericDraweeHierarchy實現(xiàn)他們的方法。
DraweeHierarchy
只有一個簡單卻重要的方法,作用獲得在Hierarchy中的FadeDrawable中儲存的頂層圖片進行顯示,F(xiàn)aceDrawable是個圖片數(shù)組,里面包含所需要的所有圖片。
Drawable getTopLevelDrawable();
SettableDraweeHierarchy
里面的接口方法均為提供給Controller調(diào)用來控制圖像,在GenericDraweeHierarchy中實現(xiàn)
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實現(xiàn)了父類的接口,提供給Controller調(diào)用來控制圖片的顯示。
其中要三個主要的Drawable對象:
FadeDrawable,它存儲了需要到的圖片資源,包括顯示圖片、加載圖片、失敗時顯示的圖片等等。繼承自ArrayDrawable,層級類圖片集合。會選擇圖片數(shù)組中的最后一張進行顯示。
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);\\隱藏數(shù)組下標<=index的圖層
以上方法 會修改 boolean[] mIsLayerOn布爾數(shù)組,來判斷是否顯示圖片。
C-DraweeController
在初始化框架時會創(chuàng)建一個PipelineDraweeControllerBuilderSupplier,并保存在SimpleDraweeView和Fresco兩個類中,以靜態(tài)變量的方式,所以Controller的創(chuàng)建有兩個入口。
創(chuàng)建Controller時通過初始化的sDraweeControllerBuilderSupplier獲得一個SimpleDraweeControllerBuilder,再用建造器模式創(chuàng)建出一個DraweeController。
事實上DraweeController的創(chuàng)建是在AbstractDraweeControllerBuilder調(diào)用實現(xiàn)了的build()方法,buildr()方法又調(diào)用了PipelineDraweeControllerBuilder獲得一個PipelineDraweeController,返回builder()后轉換成AbstractDraweeController,在最外層的調(diào)用又轉換成DraweeController。(java的多態(tài))
提供給SimpleDraweeView創(chuàng)建Controller的方法只有簡單的幾個,即在SimpleDraweeControllerBuilder中的接口方法。
SimpleDraweeControllerBuilder
SimpleDraweeControllerBuilder setCallerContext(Object callerContext); SimpleDraweeControllerBuilder setUri(Uri uri); SimpleDraweeControllerBuilder setUri(@Nullable String uriString); SimpleDraweeControllerBuilder setOldController(@Nullable DraweeController oldController); DraweeController build();
而在代碼中動態(tài)創(chuàng)建Controller再設置給SimpleDraweeView則有更多可以設置的屬性方法,這些方法保存在AbstractDraweeController中,創(chuàng)建方式在下面會寫到。
fresco的DraweeView、DraweeHierarchy、DraweeController的創(chuàng)建順序
初始化順序為:
1.DraweeView
其余都為DraweeView對象中的類,所以先有DraweeView
2.DraweeHolder (在DraweeView的init()方法中創(chuàng)建 保存在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()方法中創(chuàng)建 保存在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
并不預先創(chuàng)建,而是在使用到控件的時候動態(tài)創(chuàng)建,有兩種創(chuàng)建途徑,但兩種都是通過拿到DraweeControllerBuilderSupplier 用建造器模式去創(chuàng)建Controller
?、?調(diào)用SimpleDraweeView中的setImageURL(),源碼中已寫好創(chuàng)建Controller的代碼,只設置圖片URL
例:(SimpleDraweeView中的源碼) public void setImageURI(Uri uri, @Nullable Object callerContext) { DraweeController controller = mSimpleDraweeControllerBuilder .setCallerContext(callerContext) .setUri(uri) .setOldController(getController()) .build(); setController(controller); }
②.在代碼中使用到的時候動態(tài)創(chuàng)建,能自定義更多關于圖片的屬性方法,如需要監(jiān)聽一張GIF圖片的播放結束事件,就需要自己在代碼中動態(tài)創(chuàng)建(高版本已經(jīng)把對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);