計算控件尺寸

除非你總是需要一個100×100像素的控件,否則,你必須要重寫onMeasure

 

onMeasure方法在控件的父元素正要放置它的子控件時調用。它會問一個問題,“你想要用多大地方啊?”,然後傳入兩個參數——

widthMeasureSpec和heightMeasureSpec。它們指明控件可獲得的空間以及關於這個空間描述的元數據。

 

比返回一個結果要好的方法是你傳遞View的高度和寬度到setMeasuredDimension方法裏。

 

接下來的代碼片段給出瞭如何重寫onMeasure。注意,調用的本地空方法是來計算高度和寬度的。它們會譯解widthHeightSpec和heightMeasureSpec值,並計算出合適的高度和寬度值。

 

@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類的靜態方法getModegetSize來譯解,如下面的片段所示:

 

int specMode = MeasureSpec.getMode(measureSpec);

int specSize = MeasureSpec.getSize(measureSpec);

 

依據specMode的值,如果是AT_MOST,specSize 代表的是最大可獲得的空間;如果是EXACTLY,specSize 代表的是精確的尺寸;如果是UNSPECIFIED,對於控件尺寸來說,沒有任何參考意義。

 

當以EXACT方式標記測量尺寸,父元素會堅持在一個指定的精確尺寸區域放置View。在父元素問子元素要多大空間時,AT_MOST指示者會說給我最大的範圍。在很多情況下,你得到的值都是相同的。

 

在兩種情況下,你必須絕對的處理這些限制。在一些情況下,它可能會返回超出這些限制的尺寸,在這種情況下,你可以讓父元素選擇如何對待超出的View,使用裁剪還是滾動等技術。

 

接下來的框架代碼給出了處理View測量的典型實現:

 

@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;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章