View和ViewGroup

來源:互聯網
上載者:User

1.viewroot.java中,應用程式主動調用invalidate或setEnable等調用間接調用invalidate,invalidate中會遍曆view樹,請求重繪需要繪製的地區

   invalidate主要是確定需要重繪的地區,然後調用scheduleTraversals發起重繪請求,scheduleTraversals最終調用performTraversals遍曆view tree進行重繪

2.measure:performTraversals首先會遍曆調用view樹中所有view的measure方法來測量出view的大小

    從viewRoot的mView開始measure,這個mView是一個DecorView對象(繼承自FrameLayout,屬於ViewGroup),ViewGroup中沒有覆寫measure函數,事實上measure是一個final方法,無法覆寫,所以所有view子類的measure都是調用view的measure

      public final void measue(int widthMeasureSpec, int heightMeasureSpec);

  viewRoot在measure中根據螢幕大小和DecorView的布局(FrameLayout)確定widthMeasureSpec和heightMeasureSpec來作為參數傳入measue,measue裡回調OnMeasure,view的OnMeasure對傳入的參數通過一定的演算法算出準確的長和寬,至此,DecView本身的大小就measure完了,而DecView中的子控制項如何measure呢?

  measure是final的,但是其回調的OnMeasure是virtual的,事實上,view和viewGroup的大小都是在OnMeasure中計算出來的,預設的OnMeasure只是計算出本view或viewGroup的大小,如果是自定viewgroup,我們可以重寫onmeasure,把viewgroup的大小寫死(這樣布局xml裡寫的match_parent或者wrap_content就不起作用了),當然這樣做是不建議的,通常viewGroup的子類都會重寫Onmeasure,在裡面除了調用view的onmeasure確定自己的大小外,也確定所有子view的大小(如果子view是viewgroup,再繼續這個過程),那麼怎麼確定子view的大小呢,跟viewroot中確定decView類似,先根據父viewGroup的大小和布局確定傳給子view的measure函數的參數widthMeasureSpec和heightMeasureSpec,子view調用measureFunction Compute出子view的最終大小(這個過程封裝在viewgroup的MeasureChildren中了。

   自訂viewGroup的子類時,一般要覆寫OnMeasure方法,這這個Onmeasure方法裡,可以調用ViewGroup的MeasureChildren,也可以自己直接調用所有子view的Measure(MeasureChildren不是自動調用的,只是提供給使用者需要時手動調用的,很多android應用程式層的viewGroup子類都調用它來對子view做measure)

  在沒有measure之前,view是沒有大小的,getMeasuredWidth、getMeasuredHeight()都是0,沒有layout之前,getWidth和getHeight都是0,在layout中還可以重新確定控制項大小,所以getwith和getHeight得到的值和getMeasuredWidth、getMeasuredHeight()得到的值不一定一樣,前者是真實的繪製在螢幕上的大小,後者是measure執行完後的測量大小,當然,預設情況下,layout使用的是measure中測算的大小,除非覆寫了OnLayout,在其中重定義了大小

   所以多viewGroup子類而言,OnMeasure不是必須的,因為最終子view的大小和位置是layout決定的,onlayout才是必須的。

3. layout:measure完成後就會調用layout,同樣是遍曆view tree進行layout,layout方法也是final的:

public void layout(int left, int top, int right, int bottom) 

自訂viewgroup放入布局xml中,父布局會調用其measure和layout,所以不用管,但是其子view都是靠自己measure和layout的,子view(非viewgroup)的Onmeasure和onlayout只是被父viewgroup調用預設的方法即可,無須重寫,子viewgroup要重寫Onmeasure和onlayout,為其下面的所有子view調用measure和layout(Onmeasure可選,onlayout必須)

viewroot根據前面的measure得到的MeasureWith和MeasureHeight調用DecorView的layout(0,0,MeasureWith,MeasureHeight),DecorView重寫onlayout,在其中調用所有子view的layout,子view如果是viewgroup,則此子view再重寫onlayout,以此類推。

layout中主要是確定其子view的位置和大小(大小可以用measure得到的大小,也可以自己再定義大小),以linearlayout為例,如果是垂直布局,則每layout一個子view,把下一個子view的top加上上一個view的高度,如果是自訂的viewgroup,則根據自己設計的布局需要來確定子view的layout位置,比如可以設計一個按長度適應螢幕自動換行的viewgroup

4.draw:同樣是遍曆view
tree調用所有view的draw,draw的大小和位置已經由measure和layout確定好了

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.