/**
* MeasureSpec封裝了父布局傳遞給子布局的布局要求,每個MeasureSpec代表了一組寬度和高度的要求
* MeasureSpec由size和mode組成。
* 三種Mode:
* 1.UNSPECIFIED
* 父不沒有對子施加任何約束,子可以是任意大?。ㄒ簿褪俏粗付ǎ?
* (UNSPECIFIED在源碼中的處理和EXACTLY一樣。當(dāng)View的寬高值設(shè)置為0的時候或者沒有設(shè)置寬高時,模式為UNSPECIFIED
* 2.EXACTLY
* 父決定子的確切大小,子被限定在給定的邊界里,忽略本身想要的大小。
* (當(dāng)設(shè)置width或height為match_parent時,模式為EXACTLY,因為子view會占據(jù)剩余容器的空間,所以它大小是確定的)
* 3.AT_MOST
* 子最大可以達(dá)到的指定大小
* (當(dāng)設(shè)置為wrap_content時,模式為AT_MOST, 表示子view的大小最多是多少,這樣子view會根據(jù)這個上限來設(shè)置自己的尺寸)
*
* MeasureSpecs使用了二進(jìn)制去減少對象的分配。
*/
public class MeasureSpec {
// 進(jìn)位大小為2的30次方(int的大小為32位,所以進(jìn)位30位就是要使用int的最高位和倒數(shù)第二位也就是32和31位做標(biāo)志位)
private static final int MODE_SHIFT = 30;
// 運(yùn)算遮罩,0x3為16進(jìn)制,10進(jìn)制為3,二進(jìn)制為11。3向左進(jìn)位30,就是11 00000000000(11后跟30個0)
// (遮罩的作用是用1標(biāo)注需要的值,0標(biāo)注不要的值。因為1與任何數(shù)做與運(yùn)算都得任何數(shù),0與任何數(shù)做與運(yùn)算都得0)
private static final int MODE_MASK = 0x3 << MODE_SHIFT;
// 0向左進(jìn)位30,就是00 00000000000(00后跟30個0)
public static final int UNSPECIFIED = 0 << MODE_SHIFT;
// 1向左進(jìn)位30,就是01 00000000000(01后跟30個0)
public static final int EXACTLY = 1 << MODE_SHIFT;
// 2向左進(jìn)位30,就是10 00000000000(10后跟30個0)
public static final int AT_MOST = 2 << MODE_SHIFT;
/**
* 根據(jù)提供的size和mode得到一個詳細(xì)的測量結(jié)果
*/
// measureSpec = size + mode; (注意:二進(jìn)制的加法,不是10進(jìn)制的加法!)
// 這里設(shè)計的目的就是使用一個32位的二進(jìn)制數(shù),32和31位代表了mode的值,后30位代表size的值
// 例如size=100(4),mode=AT_MOST,則measureSpec=100+10000...00=10000..00100
public static int makeMeasureSpec(int size, int mode) {
return size + mode;
}
/**
* 通過詳細(xì)測量結(jié)果獲得mode
*/
// mode = measureSpec & MODE_MASK;
// MODE_MASK = 11 00000000000(11后跟30個0),原理是用MODE_MASK后30位的0替換掉measureSpec后30位中的1,再保留32和31位的mode值。
// 例如10 00..00100 & 11 00..00(11后跟30個0) = 10 00..00(AT_MOST),這樣就得到了mode的值
public static int getMode(int measureSpec) {
return (measureSpec & MODE_MASK);
}
/**
* 通過詳細(xì)測量結(jié)果獲得size
*/
// size = measureSpec & ~MODE_MASK;
// 原理同上,不過這次是將MODE_MASK取反,也就是變成了00 111111(00后跟30個1),將32,31替換成0也就是去掉mode,保留后30位的size
public static int getSize(int measureSpec) {
return (measureSpec & ~MODE_MASK);
}
/**
* 重寫的toString方法,打印mode和size的信息,這里省略
*/
public static String toString(int measureSpec) {
return null;
}
}
2018-04-13
?著作權(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ù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 我有個不好的習(xí)慣,就是喜歡通過故事去倒推,編劇寫劇的時候是怎么想的。渡邊純一說,他寫的故事大多是他個人經(jīng)歷的事件為...