轉帖自http://www.eoeandroid.com/thread-200062-1-1.html 1.android繪製view的過程簡單描述 簡單描述可以解釋爲:計算大小(measure),佈局座標計算(layout),繪製到屏幕(draw);下面看看每一步的動作到底是什麼, 第一步:當activity啓動的時候,觸發初始化view過程的是由Window對象的DecorView調用View(具體怎樣從xml中讀取是用LayoutInflater.from(context).inflate)對象的 public final void measure(int widthMeasureSpec, int heightMeasureSpec)方法開始的,這個方法是final類型的,也就是所有的子類都不能繼承該方法,保證android初始化view的原理不變。具體參數類值,後面會介紹。 第二步:View的measure方法 onMeasure(widthMeasureSpec, heightMeasureSpec),該方法進行實質性的view大小計算。注意:view的大小是有父view和自己的大小決定的,而不是單一決定的。這也就是爲什麼ViewGroup的子類會重新該方法,比如LinearLayout等。因爲他們要計算自己和子view的大小。View基類有自己的實現,只是設置大小。其實根據源碼來看,measure的過程本質上就是把Match_parent和wrap_content轉換爲實際大小 第三步:當measure結束時,回到DecorView,計算大小計算好了,那麼就開始佈局了,開始調用view的 public final void layout(int l, int t, int r, int b),該還是也是final類型的,目的和measure方法一樣。layout方法內部會調用onlayout(int l, int t, int r, int b )方法,二ViewGroup將此方法abstract的了,所以我們繼承ViewGroup的時候,需要重新該方法。該方法的本質是通過measure計算好的大小,計算出view在屏幕上的座標點 第四步:measure過了,layout過了,那麼就要開始繪製到屏幕上了,所以開始調用view的 public void draw(Canvas canvas)方法,此時方法不是final了,原因是程序員可以自己畫,內部會調用ondraw,我們經常需要重寫的方法。 以上就是view的大概工作過程,當然了,只是概述,細節多成馬了!!!!! 這次主要是跟分析一下measure的過程。下面進入今日主題! ---------------measure的過程! 1. public final void measure(int widthMeasureSpec, int heightMeasureSpec)的參數來源及代表的意思 這個兩個參數都是有父view傳遞過來的,也就是代表了父view的大小。其實說大小不太對,應該說是建議“規格”。他有兩部分組成,第一部分:高16位表示MODE,定義在MeasureSpec類中,有三種類型,MeasureSpec.EXACTLY:表示確定大小, MeasureSpec.AT_MOST:表示最大大小, MeasureSpec.UNSPECIFIED:不確定。第二部分:低16位表示size,既父view的大小,這就是爲什麼,我們在重寫onmeasure方法是需要:int specMode = MeasureSpec.getMode(spec); int specSize = MeasureSpec.getSize(spec);這樣調用,因爲MeasureSpec知道怎麼讀取。對於跟view(並不是我們在xml中聲明的第一個元素),而是系統的Window對象的decorVIew對象。Mode一般都爲MeasureSpec.EXACTLY ,而size分別對應屏幕寬,高。也就是Window第一次掉用的view(這個view纔是Xml中聲明的第一個元素),一般都是這個值,而對於子view來說,這連個值就是你在xml定義的屬性 android:layout_width和android:layout_height這個,當然了上面說過view的大小是有父view和子view共同決定的,所以這樣有點不對,但是來源於這兩個值。意思明白了,我們看看measure裏邊做什麼了 2.measure方法內部操作過程
android:layout_height="200dp" > <TextView android:layout_width="fill_parent" android:layout_height="100dp" android:layout_weight="1" /> <TextView android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> 上面這個例子再計算第一個TextView的時候,根據android:layout_height="100dp" 值,確定高度爲100dp,計算第二個TextView的時候,由於android:layout_height="0"爲0,所以不計算其高度,等到計算weight的時候才計算,當計算weight的時候,千萬別認爲第一個TextView已經計算過了,就不計算了,還是計算的,計算過程如下:第一個分配了100dp,還剩100dp,所以兩個textview各分50dp,所以第一個TextVIew的 150dp,第二個就爲50dp 至此,view的measure就結束了,所有的view值都結束了,大家可能發現,這個過程只用了幾個屬性: android:layout_width,android:layout_height,android:layout_weight還有marger和pading,其他的多數屬性都在ondraw時候使用, 以上分析全部是自己看源碼分析的,有錯誤之處,歡迎各位指出,以免誤導他人。 關於佈局(layout),ondraw後續有時間再補上,今天PM給分配任務,得開始幹活了,! |
【轉】android繪製view的過程之一---------計算view大小
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.