国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Android布局優化:ViewStub標簽實現延遲加載(源碼解析原理)

Raaabbit / 1154人閱讀

摘要:好處官方對的解析一個不可見大小為的試圖下面會分析這兩點實現好處顯示優酷視頻加載評論列表的,當沒有數據或者網絡加載失敗時,如果空列表的會占用資源當有數據時,才會列表的,延遲加載了布局使用步驟文件每一個必須有屬性,其中的值就是被的的可以通過這

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的試圖. (下面會分析這兩點實現)

ViewStub好處:顯示優酷視頻加載評論列表的ListView,當沒有數據或者網絡加載失敗時,如果inflate空列表的ListView會占用資源;當有數據時,才會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.查看源碼發現,可以通過設置setOnInflateListener()回調監聽獲取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();
        // 最重要的兩點
        setVisibility(GONE); // 設置不可見
        setWillNotDraw(true); // 本View不會調用onDraw()方法繪制內容
    }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // 設置試圖大小為0
    setMeasuredDimension(0, 0);
}
 public void setVisibility(int visibility) {
        if (mInflatedViewRef != null) {
            // 已經inflate()已經調用,直接獲取該inflate的View控制可見性
            View view = mInflatedViewRef.get();
            if (view != null) {
                view.setVisibility(visibility);
            } else {
                throw new IllegalStateException("setVisibility called on un-referenced view");
            }
        } else {
            // 如果沒有調用過inflate()方法,并且設置了試圖可見,就會調用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);
                // 設置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);
                // 試圖加載完成回調
                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");
        }

}

// 設置回調監聽
public void setOnInflateListener(OnInflateListener inflateListener) {
        mInflateListener = inflateListener;
    }

public static interface OnInflateListener {
     // inflated:被inflate的View
    void onInflate(ViewStub stub, View inflated);
}
4.ViewStub使用中注意事項

一旦調用setVisibility(View.VISIBLE)或者inflate()方法之后,該ViewStub將會從試圖中被移除(此時調用findViewById()是找不到該ViewStub對象).

如果指定了mInflatedId , 被inflate的layoutView的id就是mInflatedId.

被inflate的layoutView的layoutParams與ViewStub的layoutParams相同.

以上三點注意的事項可以從源碼中得知:

 //注意事項第二點
if (mInflatedId != NO_ID) {
    view.setId(mInflatedId);
}
//注意事項第一點
final int index = parent.indexOfChild(this);
parent.removeViewInLayout(this);

final ViewGroup.LayoutParams layoutParams = getLayoutParams();
if (layoutParams != null) {
     //注意事項第三點
    parent.addView(view, index, layoutParams);
} else {
    parent.addView(view, index);
}
    

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67543.html

相關文章

  • Android優化總結

    摘要:錯誤使用單利在開發中單例經常需要持有對象,如果持有的對象生命周期與單例生命周期更短時,或導致無法被釋放回收,則有可能造成內存泄漏。如果集合是類型的話,那內存泄漏情況就會更為嚴重。 目錄介紹 1.OOM和崩潰優化 1.1 OOM優化 1.2 ANR優化 1.3 Crash優化 2.內存泄漏優化 2.0 動畫資源未釋放 2.1 錯誤使用單利 2.2 錯誤使用靜態變量 2.3 ...

    sunsmell 評論0 收藏0

發表評論

0條評論

Raaabbit

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<