標籤:http res 技術分享 過程 enc alt 根據 自訂 原因
版面配置階段的含義
版面配置階段,就是程式在運行時利用布局檔案的代碼來計算出實際尺寸的過程。
版面配置階段的工作內容
兩個階段:測量階段和布局階段。
測量階段:從上到下遞迴地調用每個 View 或者 ViewGroup 的 measure() 方法,測量他們的尺寸並計算它們的位置; 布局階段:從上到下遞迴地調用每個 View 或者 ViewGroup 的 layout() 方法,把測得的它們的尺寸和位置賦值給它們。
View 或 ViewGroup 的版面配置階段
測量階段,measure()
方法被父 View 調用,在 measure()
中做一些準備和最佳化工作後,調用 onMeasure()
來進行實際的自我測量。 onMeasure()
做的事,View
和 ViewGroup
不一樣:
- View:
View
在 onMeasure()
中會計算出自己的尺寸然後儲存;
- ViewGroup:
ViewGroup
在 onMeasure()
中會調用所有子 View 的 measure()
讓它們進行自我測量,並根據子 View 計算出的期望尺寸來計算出它們的實際尺寸和位置(實際上 99.99% 的父 View 都會使用子 View 給出的期望尺寸來作為實際尺寸,原因在下期或下下期會講到)然後儲存。同時,它也會根據子 View 的尺寸和位置來計算出自己的尺寸然後儲存;
布局階段,layout()
方法被父 View 調用,在 layout()
中它會儲存父 View 傳進來的自己的位置和尺寸,並且調用 onLayout()
來進行實際的內部布局。onLayout()
做的事, View
和 ViewGroup
也不一樣:
- View:由於沒有子 View,所以
View
的 onLayout()
什麼也不做。
- ViewGroup:
ViewGroup
在 onLayout()
中會調用自己的所有子 View 的 layout()
方法,把它們的尺寸和位置傳給它們,讓它們完成自我的內部布局。
版面配置階段自訂的方式
三類:
- 重寫
onMeasure()
來修改已有的 View
的尺寸;
- 重寫
onMeasure()
來全新定製自訂 View
的尺寸;
- 重寫
onMeasure()
和 onLayout()
來全新定製自訂 ViewGroup
的內部布局。
第一類自訂的具體做法
也就是重寫 onMeasure()
來修改已有的 View
的尺寸的具體做法:
- 重寫
onMeasure()
方法,並在裡面調用 super.onMeasure()
,觸發原有的自我測量;
- 在
super.onMeasure()
的下面用 getMeasuredWidth()
和 getMeasuredHeight()
來擷取到之前的測量結果,並使用自己的演算法,根據測量結果計算出新的結果;
- 調用
setMeasuredDimension()
來儲存新的結果。
第二類全新定製自訂
View
的尺寸
需要在計算的同時,保證計算結果滿足父 View 給出的的尺寸限制
- 由來:開發人員的要求(布局檔案中
layout_
打頭的屬性)經過父 View 處理計算後的更精確的要求;
- 限制的分類:
UNSPECIFIED
:不限制
AT_MOST
:限制上限
EXACTLY
:限制固定值
- 全新定義自訂 View 尺寸的方式
- 重新
onMeasure()
,並計算出 View 的尺寸;
- 使用
resolveSize()
來讓子 View 的計算結果符合父 View 的限制(當然,如果你想用自己的方式來滿足父 View 的限制也行)。
第三類定製 Layout 內部布局的方式
- 重寫
onMeasure()
來計算內部布局
- 重寫
onLayout()
來擺放子 View
- 調用每個子 View 的
measure()
來計運算元 View 的尺寸
- 計運算元 View 的位置並儲存子 View 的位置和尺寸
- 計算自己的尺寸並用
setMeasuredDimension()
儲存
計運算元 View 的尺寸,關鍵在於 measure()
方法的兩個參數——也就是子 View 的兩個 MeasureSpec
的計算。
- 子 View 的 MeasureSpec 的計算方式:
- 結合開發人員的要求(xml 中
layout_
打頭的屬性)和自己的可用空間(自己的尺寸上限 - 已用尺寸)
- 尺寸上限根據自己的
MeasureSpec
中的 mode 而定
- EXACTLY / AT_MOST:尺寸上限為
MeasureSpec
中的 size
- UNSPECIFIED:尺寸無上限
在 onLayout()
裡調用每個子 View 的 layout()
,讓它們儲存自己的位置和尺寸。
Android布局基礎