本教程內容來源于:http://fresco-cn.org
采用 知識共享 署名 4.0 國際 許可協議 進行許可
總有一些時候,DraweeViews是滿足不了需求的,在展示圖片的時候,我們還需要展示一些其他的內容,或者支持一些其他的操作。在同一個View里,我們可能會想顯示一張或者多張圖。
在自定義View中,Fresco 提供了兩個類來負責圖片的展現:
DraweeHolder 單圖情況下用。MultiDraweeHolder 多圖情況下用。Android 呈現View對象,只有View對象才能得到一些系統事件的通知。DraweeViews
處理這些事件通知,高效地管理內存。使用DraweeHolder時,你需要自己實現這幾個方法。
如果沒按照以下步驟實現的話,很可能會引起內存泄露
當圖片不再在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);
}
Drawable drawable = mDraweeHolder.getHierarchy().getTopLevelDrawable();
drawable.setBounds(...);
否則圖片將不會出現
verifyDrawable:@Override
protected boolean verifyDrawable(Drawable who) {
if (who == mDraweeHolder.getHierarchy().getTopLevelDrawable()) {
return true;
}
// 對其他Drawable的驗證邏輯
}
invalidateDrawable 處理了圖片占用的那塊區(qū)域。這同樣需要非常小心和細致
我們推薦如下實現構造函數:
init方法。init方法中執(zhí)行初始化操作。即,不要在構造函數中用this來調用另外一個構造。
這樣可以保證,不管調用哪個構造,都可以正確地執(zhí)行初始化流程。然后在init方法中創(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);
和DraweeHolder相比,MultiDraweeHolder有 add, 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那樣。