onMeasure方法在控件的父元素正要放置它的子控件時調用.它會問一個問題,「你想要用多大地方啊?」,而後傳入兩個參數——widthMeasureSpec和heightMeasureSpec.
它們指明控件可得到的空間以及關於這個空間描述的元數據.
比返回一個結果要好的方法是你傳遞View的高度和寬度到setMeasuredDimension方法裏.
接下來的代碼片斷給出瞭如何重寫onMeasure.注意,調用的本地空方法是來計算高度和寬度的.它們會譯解widthHeightSpec和heightMeasureSpec值,並計算出合適的高度和寬度值.
java代碼:
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
- int measuredHeight = measureHeight(heightMeasureSpec);
- int measuredWidth = measureWidth(widthMeasureSpec);
- setMeasuredDimension(measuredHeight, measuredWidth);
- }
-
- private int measureHeight(int measureSpec) {
-
-
- // Return measured widget height.
- }
-
- private int measureWidth(int measureSpec) {
-
- // Return measured widget width.
- }
-
複製代碼
邊界參數——widthMeasureSpec和heightMeasureSpec ,效率的緣由以整數的方式傳入。在它們使用以前,首先要作的是使用MeasureSpec類的靜態方法getMode和getSize來譯解,以下面的片斷所示:
java代碼:
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
-
複製代碼
依據specMode的值,若是是AT_MOST,specSize 表明的是最大可得到的空間;若是是EXACTLY,specSize 表明的是精確的尺寸;若是是UNSPECIFIED,對於控件尺寸來講,沒有任何參考意義。
當以EXACT方式標記測量尺寸,父元素會堅持在一個指定的精確尺寸區域放置View。在父元素問子元素要多大空間時,AT_MOST指示者會說給我最大的範圍。在不少狀況下,你獲得的值都是相同的。
在兩種狀況下,你必須絕對的處理這些限制。在一些狀況下,它可能會返回超出這些限制的尺寸,在這種狀況下,你能夠讓父元素選擇如何對待超出的View,使用裁剪仍是滾動等技術。
接下來的框架代碼給出了處理View測量的典型實現:
java代碼:
- @Override
-
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
- int measuredHeight = measureHeight(heightMeasureSpec);
-
- int measuredWidth = measureWidth(widthMeasureSpec);
-
- setMeasuredDimension(measuredHeight, measuredWidth);
-
- }
-
- private int measureHeight(int measureSpec) {
-
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
-
- // Default size if no limits are specified.
-
- int result = 500;
- if (specMode == MeasureSpec.AT_MOST){
-
- // Calculate the ideal size of your
- // control within this maximum size.
- // If your control fills the available
- // space return the outer bound.
-
- result = specSize;
- }
- else if (specMode == MeasureSpec.EXACTLY){
-
- // If your control can fit within these bounds return that value.
- result = specSize;
- }
-
- return result;
- }
-
- private int measureWidth(int measureSpec) {
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
-
- // Default size if no limits are specified.
- int result = 500;
- if (specMode == MeasureSpec.AT_MOST){
- // Calculate the ideal size of your control
- // within this maximum size.
- // If your control fills the available space
- // return the outer bound.
- result = specSize;
- }
-
- else if (specMode == MeasureSpec.EXACTLY){
- // If your control can fit within these bounds return that value.
-
- result = specSize;
- }
-
- return result;
- }