摘要:好處官方對的解析一個不可見大小為的試圖下面會分析這兩點(diǎn)實(shí)現(xiàn)好處顯示優(yōu)酷視頻加載評論列表的,當(dāng)沒有數(shù)據(jù)或者網(wǎng)絡(luò)加載失敗時,如果空列表的會占用資源當(dāng)有數(shù)據(jù)時,才會列表的,延遲加載了布局使用步驟文件每一個必須有屬性,其中的值就是被的的可以通過這
1.ViewStub好處
ViewStub is a lightweight view with no dimension that doesn’t draw anything or participate in the layout. it"s an invisible, zero-sized View that can be used to lazily inflate layout resources at runtime.
Android官方對ViewStub的解析:1.ViewStub一個不可見2.大小為0的試圖. (下面會分析這兩點(diǎn)實(shí)現(xiàn)) ViewStub好處:顯示優(yōu)酷視頻加載評論列表的ListView,當(dāng)沒有數(shù)據(jù)或者網(wǎng)絡(luò)加載失敗時,如果inflate空列表的ListView會占用資源;當(dāng)有數(shù)據(jù)時,才會inflate列表的ListView,延遲加載了布局.2.ViewStub使用步驟
stub_list.xml文件
每一個ViewStub必須有android:layout屬性,其中android:inflatedId的值就是被inflate的View的ID.
findViewById(R.id.list_stub)).setVisibility(View.VISIBLE);
// or
ListView listView = (ListView)((ViewStub) findViewById(R.id.list_stub)).inflate();
可以通過這兩種方式inflate布局,第二種方式inflate布局不需要findViewById()找ListView.查看源碼發(fā)現(xiàn),可以通過設(shè)置setOnInflateListener()回調(diào)監(jiān)聽獲取inflate的View.
3.ViewStub源碼分析public ViewStub(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewStub, defStyleAttr, defStyleRes); // 解析android:inflatedId屬性,其值是被inflate的View的ID mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID); // 解析android:layout屬性,其值是被inflate的View布局 mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0); // 解析android:id屬性,可以通過findViewByID找到該ViewStub mID = a.getResourceId(R.styleable.ViewStub_id, NO_ID); a.recycle(); // 最重要的兩點(diǎn) setVisibility(GONE); // 設(shè)置不可見 setWillNotDraw(true); // 本View不會調(diào)用onDraw()方法繪制內(nèi)容 }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 設(shè)置試圖大小為0 setMeasuredDimension(0, 0); }
public void setVisibility(int visibility) { if (mInflatedViewRef != null) { // 已經(jīng)inflate()已經(jīng)調(diào)用,直接獲取該inflate的View控制可見性 View view = mInflatedViewRef.get(); if (view != null) { view.setVisibility(visibility); } else { throw new IllegalStateException("setVisibility called on un-referenced view"); } } else { // 如果沒有調(diào)用過inflate()方法,并且設(shè)置了試圖可見,就會調(diào)用inflate()加載布局 super.setVisibility(visibility); if (visibility == VISIBLE || visibility == INVISIBLE) { inflate(); } } }
public View inflate() { final ViewParent viewParent = getParent(); if (viewParent != null && viewParent instanceof ViewGroup) { if (mLayoutResource != 0) { final ViewGroup parent = (ViewGroup) viewParent; final LayoutInflater factory; if (mInflater != null) { factory = mInflater; } else { factory = LayoutInflater.from(mContext); } // 加載真正的去加載布局試圖 final View view = factory.inflate(mLayoutResource, parent, false); // 設(shè)置mInflatedId給inflate的View if (mInflatedId != NO_ID) { view.setId(mInflatedId); } // 獲取ViewStub在視圖中的位置 final int index = parent.indexOfChild(this); // 從視圖移除ViewStub parent.removeViewInLayout(this); final ViewGroup.LayoutParams layoutParams = getLayoutParams(); // 將inflate的試圖加載父布局中,位置是被移除的ViewStub位置(也就是該ViewStub被替換成layoutView) if (layoutParams != null) { parent.addView(view, index, layoutParams); } else { parent.addView(view, index); } mInflatedViewRef = new WeakReference(view); // 試圖加載完成回調(diào) if (mInflateListener != null) { mInflateListener.onInflate(this, view); } return view; } else { throw new IllegalArgumentException("ViewStub must have a valid layoutResource"); } } else { throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent"); }
}
// 設(shè)置回調(diào)監(jiān)聽 public void setOnInflateListener(OnInflateListener inflateListener) { mInflateListener = inflateListener; } public static interface OnInflateListener { // inflated:被inflate的View void onInflate(ViewStub stub, View inflated); }4.ViewStub使用中注意事項(xiàng)
一旦調(diào)用setVisibility(View.VISIBLE)或者inflate()方法之后,該ViewStub將會從試圖中被移除(此時調(diào)用findViewById()是找不到該ViewStub對象).
如果指定了mInflatedId , 被inflate的layoutView的id就是mInflatedId.
被inflate的layoutView的layoutParams與ViewStub的layoutParams相同.
以上三點(diǎn)注意的事項(xiàng)可以從源碼中得知:
//注意事項(xiàng)第二點(diǎn) if (mInflatedId != NO_ID) { view.setId(mInflatedId); } //注意事項(xiàng)第一點(diǎn) final int index = parent.indexOfChild(this); parent.removeViewInLayout(this); final ViewGroup.LayoutParams layoutParams = getLayoutParams(); if (layoutParams != null) { //注意事項(xiàng)第三點(diǎn) parent.addView(view, index, layoutParams); } else { parent.addView(view, index); }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67543.html
摘要:錯誤使用單利在開發(fā)中單例經(jīng)常需要持有對象,如果持有的對象生命周期與單例生命周期更短時,或?qū)е聼o法被釋放回收,則有可能造成內(nèi)存泄漏。如果集合是類型的話,那內(nèi)存泄漏情況就會更為嚴(yán)重。 目錄介紹 1.OOM和崩潰優(yōu)化 1.1 OOM優(yōu)化 1.2 ANR優(yōu)化 1.3 Crash優(yōu)化 2.內(nèi)存泄漏優(yōu)化 2.0 動畫資源未釋放 2.1 錯誤使用單利 2.2 錯誤使用靜態(tài)變量 2.3 ...
閱讀 1428·2021-10-08 10:05
閱讀 3079·2021-09-26 10:10
閱讀 890·2019-08-30 15:55
閱讀 515·2019-08-26 11:51
閱讀 451·2019-08-23 18:10
閱讀 3870·2019-08-23 15:39
閱讀 672·2019-08-23 14:50
閱讀 777·2019-08-23 14:46