1. 程式人生 > >自定義view佈局過程詳解

自定義view佈局過程詳解

佈局過程,就是程式在執行時利用佈局檔案的程式碼來計算出實際尺寸的過程。

佈局分為兩個階段:測量階段和佈局階段。

測量階段:從上到下遞迴地呼叫每個 View 或者 ViewGroup 的 measure() 方法,測量他們的尺寸並計算它們的位置; 

佈局階段:從上到下遞迴地呼叫每個 View 或者 ViewGroup 的 layout() 方法,把測得的它們的尺寸和位置賦值給它們;

 

View或ViewGroup的佈局過程

  1. 測量階段,measure() 方法被父 View 呼叫,在 measure() 中做一些準備和優化工作後,呼叫 onMeasure()

     來進行實際的自我測量。 onMeasure() 做的事,View 和 ViewGroup 不一樣:

    1. ViewView 在 onMeasure() 中會計算出自己的尺寸然後儲存,儲存使用setMeasuredDimension()方法;
    2. ViewGroupViewGroup 在 onMeasure() 中會呼叫所有子 View 的 measure() 讓它們進行自我測量,並根據子 View 計算出的期望尺寸來計算出它們的實際尺寸和位置然後儲存。同時,它也會根據子 View 的尺寸和位置來計算出自己的尺寸然後儲存;
  2. 佈局階段,layout() 方法被父 View 呼叫,在 layout() 中它會儲存父 View 傳進來的自己的位置和尺寸,並且呼叫 onLayout() 來進行實際的內部佈局。onLayout() 做的事, View 和 ViewGroup 也不一樣:

    1. View:由於沒有子 View,所以 View 的 onLayout() 什麼也不做。
    2. ViewGroupViewGroup 在 onLayout()
       中會呼叫自己的所有子 View 的 layout() 方法,把它們的尺寸和位置傳給它們,讓它們完成自我的內部佈局。

 

重寫 onMeasure() 來修改已有的 View 的尺寸具體做法:

  1. 重寫 onMeasure() 方法,並在裡面呼叫 super.onMeasure(),觸發原有的自我測量;
  2. 在 super.onMeasure() 的下面用 getMeasuredWidth() 和 getMeasuredHeight() 來獲取到之前的測量結果,並使用自己的演算法,根據測量結果計算出新的結果;
  3. 呼叫 setMeasuredDimension() 來儲存新的結果。