MeasureSpec三種模式

在自定義View和ViewGroup的時(shí)候冬念,我們經(jīng)常會(huì)遇到int型的MeasureSpec來表示一個(gè)組件的大小趁窃,這個(gè)變量里面不僅有組件的尺寸大小,還有大小的模式急前。
這個(gè)大小的模式醒陆,有點(diǎn)難以理解。在系統(tǒng)中組件的大小模式有三種:

1.精確模式(MeasureSpec.EXACTLY)
在這種模式下裆针,尺寸的值是多少刨摩,那么這個(gè)組件的長或?qū)捑褪嵌嗌佟?br> 2.最大模式(MeasureSpec.AT_MOST)
這個(gè)也就是父組件,能夠給出的最大的空間世吨,當(dāng)前組件的長或?qū)捵畲笾荒転檫@么大澡刹,當(dāng)然也可以比這個(gè)小。
3.未指定模式(MeasureSpec.UNSPECIFIED)

這個(gè)就是說耘婚,當(dāng)前組件罢浇,可以隨便用空間,不受限制。

可能有很多人想不通嚷闭,一個(gè)int型整數(shù)怎么可以表示兩個(gè)東西(大小模式和大小的值)攒岛,一個(gè)int類型我們知道有32位。而模式有三種凌受,要表示三種狀 態(tài)阵子,至少得2位二進(jìn)制位思杯。于是系統(tǒng)采用了最高的2位表示模式胜蛉。如圖:

32位

最高兩位是00的時(shí)候表示"未指定模式"。即MeasureSpec.UNSPECIFIED
最高兩位是01的時(shí)候表示"'精確模式"色乾。即MeasureSpec.EXACTLY
最高兩位是11的時(shí)候表示"最大模式"誊册。即MeasureSpec.AT_MOST

很多人一遇到位操作頭就大了,為了操作簡便暖璧,于是系統(tǒng)給我提供了一個(gè)MeasureSpec工具類案怯。
這個(gè)工具類有四個(gè)方法和三個(gè)常量(上面所示)供我們使用:

//這個(gè)是由我們給出的尺寸大小和模式生成一個(gè)包含這兩個(gè)信息的int變量,這里這個(gè)模式這個(gè)參數(shù)澎办,傳三個(gè)常量中的一個(gè)嘲碱。
public static int makeMeasureSpec(int size, int mode)

//這個(gè)是得到這個(gè)變量中表示的模式信息,將得到的值與三個(gè)常量進(jìn)行比較局蚀。
public static int getMode(int measureSpec)

//這個(gè)是得到這個(gè)變量中表示的尺寸大小的值麦锯。
public static int getSize(int measureSpec)

//把這個(gè)變量里面的模式和大小組成字符串返回來,方便打日志
public static String toString(int measureSpec)

MeasureSpec.EXACTLY:使用measureSpec中size的值作為寬高的精確值
當(dāng)我們將控件的layout_width或layout_height指定為具體數(shù)值時(shí)如andorid:layout_width="50dip"琅绅,或者為FILL_PARENT是扶欣,都是控件大小已經(jīng)確定的情況,都是精確尺寸千扶。
MeasureSpec.AT_MOST:使用measureSpec中size的值作為最大值料祠,采用不超過這個(gè)值的最大允許值
當(dāng)控件的layout_width或layout_height指定為WRAP_CONTENT時(shí),控件大小一般隨著控件的子空間或內(nèi)容進(jìn)行變化澎羞,此時(shí)控件尺寸只要不超過父控件允許的最大尺寸即可髓绽。因此,此時(shí)的mode是AT_MOST妆绞,size給出了父控件允許的最大尺寸顺呕。
MeasureSpec.UNSPECIFIED是未指定尺寸,這種情況不多

以scrollview嵌套listview為例摆碉,我們重寫onMesure方法:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.makeMeasureSpec(1000>>2,MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, width);
}

1000的二進(jìn)制:1111101000,右移2位后:11111010塘匣,十進(jìn)制為:250,這樣就指定了listview的高度為250px以內(nèi)的最大允許值(一般就是250)
把AT_MOST改為EXACTLY,則精確指定listview高度值為250px巷帝,如果listview內(nèi)容全部顯示的高度為500px(大于250px)忌卤,那么當(dāng)measureSpec中size的值為250px(小于500px)時(shí),效果是一樣的楞泼。如果設(shè)置的measureSpec中size的值大于listview內(nèi)容全部顯示的高度驰徊,那么設(shè)置成AT_MOST時(shí)笤闯,最多顯示listview內(nèi)容全部顯示的高度,而EXACTLY還是顯示measureSpec中size的值棍厂,所以EXACTLY在這種情況下颗味,后面會(huì)留有空白高度(measureSpec中size的值大于listview內(nèi)容全部顯示的高度的部分顯示為空白)
所以,一般這樣寫可以讓listview正確測量:

int width = MeasureSpec.makeMeasureSpec(Integer.*MAX_VALUE*>>2,MeasureSpec.*AT_MOST*);

MAX_VALUE右移2位后牺弹,即使不是最大整數(shù)了浦马,listview的高度也一般不可能超過它,第一個(gè)參數(shù)有個(gè)最大值的限制:1073741823(二進(jìn)制的30個(gè)1)张漂,MAX_VALUE是1個(gè)0加上31個(gè)1(二進(jìn)制)晶默,所以也可以右移1位,但是由于最前面兩位表示mode航攒,而不是size磺陡,所有右移1位和右移2位是一樣的(前面兩位的值都會(huì)被mode的代碼覆蓋)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漠畜,一起剝皮案震驚了整個(gè)濱河市币他,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌憔狞,老刑警劉巖蝴悉,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異躯喇,居然都是意外死亡辫封,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門廉丽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倦微,“玉大人,你說我怎么就攤上這事正压⌒栏#” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵焦履,是天一觀的道長拓劝。 經(jīng)常有香客問我,道長嘉裤,這世上最難降的妖魔是什么郑临? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮屑宠,結(jié)果婚禮上厢洞,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好躺翻,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布丧叽。 她就那樣靜靜地躺著,像睡著了一般公你。 火紅的嫁衣襯著肌膚如雪踊淳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天陕靠,我揣著相機(jī)與錄音迂尝,去河邊找鬼。 笑死懦傍,一個(gè)胖子當(dāng)著我的面吹牛雹舀,可吹牛的內(nèi)容都是我干的芦劣。 我是一名探鬼主播粗俱,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼虚吟!你這毒婦竟也來了寸认?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤串慰,失蹤者是張志新(化名)和其女友劉穎偏塞,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邦鲫,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡灸叼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庆捺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片古今。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖滔以,靈堂內(nèi)的尸體忽然破棺而出捉腥,到底是詐尸還是另有隱情,我是刑警寧澤你画,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布抵碟,位于F島的核電站,受9級(jí)特大地震影響坏匪,放射性物質(zhì)發(fā)生泄漏拟逮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一适滓、第九天 我趴在偏房一處隱蔽的房頂上張望敦迄。 院中可真熱鬧,春花似錦、人聲如沸颅崩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沿后。三九已至沿彭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尖滚,已是汗流浹背喉刘。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漆弄,地道東北人睦裳。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像撼唾,于是被迫代替她去往敵國和親廉邑。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容