【Android】MeasureSpec簡述

在 View 的 onMeasure 回調(diào)中,有兩個參數(shù)widthMeasureSpecheightMeasureSpec,分別代表當(dāng)前View的寬與高的MeasureSpec

1. MeasureSpec 的本質(zhì)

MeasureSpec 的本質(zhì)是一個整型值。
眾所周知,Java/Kt 中的整型占用了 32 位;而 MeasureSpec 的前2位表示測量模式(mode),后30位表示測量大?。╯ize),實現(xiàn)了一個整型保存兩個信息的目的。

通過MeasureSpec.getMode(measureSpec)靜態(tài)方法可以獲取一個 MeasureSpec 的 mode,MeasureSpec.getSize(measureSpec)可以獲取到 size。

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val wMode = MeasureSpec.getMode(widthMeasureSpec) // 水平方向的測量模式
        val wSize = MeasureSpec.getSize(widthMeasureSpec) // 水平方向的測量大小
        val hMode = MeasureSpec.getMode(heightMeasureSpec) // 豎直方向的測量模式
        val hSize = MeasureSpec.getSize(heightMeasureSpec) // 豎直方向的測量大小
    }

通過MeasureSpec.makeMeasureSpec(size, mode)靜態(tài)方法,可以將 mode 與 size 合成為一個 MeasureSpec。

size 不用多說,表示寬或高的長度,單位是像素。

mode 分為三種:MeasureSpec.UNSPECIFIEDMeasureSpec.EXACTLY、MeasureSpec.AT_MOST;其中,MeasureSpec.UNSPECIFIED基本不用,可以忽視。也就是說,常用的 MeasureSpec 只有EXACTLYAT_MOST兩種。
顧名思義,EXACTLY即為精確模式,表示這個 ViewGroup 的寬或高是確定值size;而AT_MOST則是最大模式,表示這個 View 的寬或高最大能達(dá)到size,真實長度根據(jù)實際情況而定。

onMeasure回調(diào)中,傳入的 MeasureSpec 是根據(jù)當(dāng)前 View 的父容器的 MeasureSpec 和當(dāng)前 View 在布局中的layout_width、layout_height 屬性決定的。

2. MeasureSpec 的計算過程

那么,onMeasure中的兩個參數(shù)是如何得到的呢?
事實上,一般來講,當(dāng)一個 ViewGroup 測量自身的時候,會先遍歷它的子 View,并調(diào)用子 View 的measure方法進(jìn)行測量,而measure方法又會調(diào)用onMeasure回調(diào)。
也就是說,View的onMeasure回調(diào)方法中的兩個參數(shù)是父容器計算并傳遞過來的。

下表反應(yīng)了正常情況下父容器是如何得到一個子 View 的 MeasureSpec 的。其中橫軸表示父容器的 MeasureSpec,縱軸表示了該 View 在布局文件中設(shè)置的寬或高,表中為該 View 的 MeasureSpec 的 mode 與 size。

子View在xml中 \ 父MeasureSpec EXACTLY AT_MOST
確定的數(shù)值 mode: EXACTLY
size: 布局中設(shè)置的大小
mode: EXACTLY
size: 布局中設(shè)置的大小
wrap_content mode: AT_MOST
size: 父容器specSize
mode: AT_MOST
size: 父容器specSize
match_parent mode: EXACTLY
size: 父容器specSize
mode: AT_MOST
size: 父容器specSize

也就是說:

  1. 當(dāng)布局中寬或高填寫的固定值,那么對應(yīng)的 mode 為 EXACTLY ,size 為填寫的值;
  2. 當(dāng)布局中的寬或高填寫的wrap_content,那么對應(yīng)的 mode 為 AT_MOST,size 為父容器的 size;
  3. 當(dāng)布局中的寬或高填寫的match_parent,那么顧名思義,mode 和 size 都與父容器相同。
最后編輯于
?著作權(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)容