1.View的繪制流程
一般來說View的繪制流程分為三個(gè)步驟
measure(測量)钾埂,通過measure來確定View的大小(即寬高)
layout(布局),通過layout來確定View的位置(即在屏幕的具體位置)
draw(繪制),珍促,通過draw來繪制View所需要顯示的內(nèi)容
2.從哪里入口
在開發(fā)中,我們通常都會(huì)在Activity里寫這么一句話setContentView(int)來實(shí)現(xiàn)我們想要的布局剩愧,頁面通常都是依附于Window之上的猪叙,而DecorView是窗口上最頂級的視圖,DecorView本身也是繼承于FrameLayout仁卷,它里面的布局如下穴翩。
所以我們在調(diào)用setContentView的時(shí)候,其實(shí)就是把我們的布局給添加到R.id.content的布局上面锦积,然后我們在回來View的繪制.
3.ViewRootImp
通過ViewRoot來繪制View芒帕,而ViewRoot的實(shí)現(xiàn)類為ViewRootImp,當(dāng)Activity創(chuàng)建完成之后丰介,會(huì)將DecorView添加到窗口Window之中背蟆,同時(shí)會(huì)創(chuàng)建ViewRootImp對象,將ViewRootImp和DecorView關(guān)聯(lián)哮幢,我們在自定義View的時(shí)候調(diào)用View.invalidate()或者View.requestLayout()要求View進(jìn)行重繪的時(shí)候带膀,在View的內(nèi)部會(huì)不斷的向上查找父布局,直到最外層的DecorView之后家浇,會(huì)調(diào)用與之關(guān)聯(lián)的ViewRootImp的performTraversals方法本砰,開始真正的繪制View。View的繪制流程是從ViewRoot的performTraversals開始的钢悲,首先在performMeasure會(huì)開始DecorView的measure方法点额,在measure方法里會(huì)調(diào)用onMeasure方法,在onMeasure方法會(huì)對DecorView的所有子View進(jìn)行測量莺琳,但是父容易怎么測量子容器的大小呢还棱,這個(gè)時(shí)候其實(shí)是將Measure事件傳遞到子容易,讓他自身進(jìn)行測量惭等,如此反復(fù)下去珍手,直接子View是非容器類控件才停止測量,這樣辞做,我們的整個(gè)視圖樹才算測量完成琳要。同理,performLayout和performDraw也一樣秤茅、
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
try {
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}