轉至:http://www.cnblogs.com/xingmeng/archive/2012/08/09/2629873.html
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;
- }