3.1 控件架構(gòu)
- 通過ViewGroup整個控件組成一個控件樹春寿。
Activity->PhoneWindow->DecorView->Title和ContentView(contentView本質(zhì)上為一個Framelayout)
- DecorView將要顯示的內(nèi)容呈現(xiàn)在了PhoneWindow上官辈。
所有View的監(jiān)聽事件都是通過WindowManagerService來進行接收喜德。
當(dāng)程序在onCreate()中調(diào)用setContentView()之后ActivityManagerService會回調(diào)onResume()方法变逃,此時系統(tǒng)才會把整個DecorView添加到PhoneWindow中振愿,并顯示出來侍咱,從而最終完成界面的繪制柠并。所以requestWindowFeature(Window.Feature_NO_TITLE)要在setContentView之前調(diào)用岭接。
3.2 View的測量
說到測量首先得說下MeasuerSpec的作用:
1 MeasureSpec封裝了父布局傳遞給子View的布局要求富拗。
2 MeasureSpec可以表示寬和高
3 MeasureSpec由size和mode組成
測量模式分為三種:
EXACTLY : width或height為具體值時,或者為match_parent時鸣戴。
AT_MOST:width或height為wrap_content時啃沪。
UNSPECIFIED:不指定,View想多大就多大窄锅,自定義View時才有機會使用创千。
注意:View類默認(rèn)的onMeasure()方法只支持EXACTLY模式,所以在自定義控件的時候必須重寫onMeasure()方法指定wrap_content時的大小入偷,才能使View支持wrap_content屬性追驴。
- onMeasure()最終調(diào)用setMeasuredDimension(measureWidth(widthMeasureSpec), measureWidth(heightMeasureSpec))方法。
measureWidth()方法的基本模板:
private int measureWidth(int measureSpec){
int result =0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if(specMode == MeasureSpec.EXACTLY){
result = specSize;
}else{
result =200;//需要具體測量疏之,這里給定具體值
if(specMode == MeasureSpec.AT_MOST){
result = Math.min(result, specSize);//取最小值
}
}
return result;
}