MeasureSpec總結(jié)

MeasureSpec

View的LayoutParams根據(jù)父容器所施加的規(guī)則轉(zhuǎn)換成對應(yīng)的MeasureSpec,然后根據(jù)這個MeasureSpec來測量出View的寬高。MeasureSpec代表一個32位int值,高2位代表SpecMode(測量模式),低30位代表SpecSize(在某個測量模式下的規(guī)格大小)

//獲取SpecSize:
int specSize = MeasureSpec.getSize(measureSpec)
//獲取specMode
int measureSpec=MeasureSpec.makeMeasureSpec(size, mode);

SpecMode一共有三種:

  1. UNSPECIFIED :父容器不對View進行任何限制,要多大給多大,一般用于系統(tǒng)內(nèi)部

  2. EXACTLY:父容器檢測到View所需要的精確大小,這時候View的最終大小就是SpecSize所指定的值,對應(yīng)LayoutParams中的match_parent和具體數(shù)值這兩種模式

  3. AT_MOST :對應(yīng)View的默認大小,不同View實現(xiàn)不同,View的大小不能大于父容器的SpecSize,對應(yīng)LayoutParams中的wrap_content

MeasureSpec和LayoutParams的對應(yīng)關(guān)系

View的MeasureSpec由父容器的MeasureSpec和自身的LayoutParams共同決定。

對于普通View來說,View的measure過程由ViewGroup傳遞過來,measureChildWithMargins源碼

protected void measureChildWithMargins(View child,
        int parentWidthMeasureSpec, int widthUsed,
        int parentHeightMeasureSpec, int heightUsed) {
    final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();

    final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
            mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
                    + widthUsed, lp.width);
    final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
            mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
                    + heightUsed, lp.height);

    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}

measureChildWithMargins()方法對子元素進行measure,在調(diào)用子元素的measure方法之前先通過
measureChildWithMargins()方法得到子元素的MeasureSpec,子元素的MeasureSpec與父容器的MeasureSpec和自身的LayoutParams有關(guān),還與view的margin和padding有關(guān)。

View 的MeasureSpec創(chuàng)建規(guī)則(getChildMeasureSpec方法的表格呈現(xiàn))

  • 當(dāng)View采用固定寬/高時(即設(shè)置固定的dp/px),不管父容器的MeasureSpec是什么,View的MeasureSpec都是EXACTLY模式,并且大小遵循我們設(shè)置的值。
  • 當(dāng)View的寬/高是match_parents時,如果父容器的模式是精準模式,那么View也是精準模式并且其大小是父容器的剩余空間;如果父容器是最大模式那么View也是最大模式并且其大小不會超過父容器的剩余空間
  • 當(dāng)View的寬/高是wrap_content時,View的MeasureSpec都是AT_MOST模式并且其大小不能超過父容器的剩余空間。

只要提供父容器的MeasureSpec和子元素的LayoutParams,就可以確定出子元素的MeasureSpec,進一步便可以確定出測量后的大小。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容