例1. 缺少默認(rèn)值 | 自己寫的
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int finalWidth, finalHeight;
// 不明
finalWidth = getSuggestedMinimumWidth();
finalHeight = getSuggestedMinimumHeight();
if (widthMode == MeasureSpec.EXACTLY) {
finalWidth = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
int padding = getPaddingLeft() + getPaddingRight();
finalWidth += padding;
}
if (heightMode == MeasureSpec.EXACTLY) {
finalHeight = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
int padding = getPaddingTop() + getPaddingBottom();
finalHeight += padding;
}
setMeasuredDimension(finalWidth, finalHeight);
}
① 上面的例子中缺少默認(rèn)值,所以高度為0
②
例2. 指定默認(rèn)寬高 | 對(duì)第三種測(cè)量模式UNSPECIFIED的理解
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = 100;
int desiredHeight = 100;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
解決的方法總結(jié):
- 指定一個(gè)默認(rèn)的內(nèi)部寬高喻括,例如本方法中的desiredWidth = 100。
- 判斷當(dāng)MeasureSpec的模式為AT_MOST(對(duì)應(yīng)于wrap_content)時(shí)驰徊,設(shè)置結(jié)果為設(shè)置的值(最大為我們?cè)O(shè)置的值,如果小于設(shè)置值就設(shè)置為specSize)堕阔。
- 判斷當(dāng)MeasureSpec的模式為非AT_MOST時(shí)棍厂,直接設(shè)置為系統(tǒng)的測(cè)量值即可。
- 設(shè)置值沒有特定的標(biāo)準(zhǔn)超陆,以實(shí)際情況為準(zhǔn)牺弹。
以上作者:Jinlin
鏈接:http://www.reibang.com/p/95b98edda6ac
例3. 寬高默認(rèn)值
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec),
measureHeight(heightMeasureSpec));
}
private int measureHeight(int measureSpec) {
int result = 0;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
result=75;
if (mode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}
return result;
}
private int measureWidth(int measureSpec) {
int result = 0;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = 75;//根據(jù)自己的需要更改
if (mode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}
return result;
}
①
②
③ UNSPECIFIED 這種模式不指定測(cè)量模式,view大小沒有限制时呀,想多大就多大张漂。
版權(quán)聲明:本文為CSDN博主「mxiaoyem」的原創(chuàng)文章,遵循CC 4.0 by-sa版權(quán)協(xié)議谨娜,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明航攒。
原文鏈接:https://blog.csdn.net/mxiaoyem/article/details/51077054
另外(https://www.cnblogs.com/wjtaigwh/p/6600035.html)
如果我們的自定義控件在布局文件中,只需要設(shè)置指定的具體寬高趴梢,或者M(jìn)ATCH_PARENT 的情況漠畜,我們可以不用重寫onMeasure方法。
但如果自定義控件需要設(shè)置包裹內(nèi)容WRAP_CONTENT 坞靶,我們需要重寫onMeasure方法憔狞,為控件設(shè)置需要的尺寸;默認(rèn)情況下WRAP_CONTENT 的處理也將填充整個(gè)父控件彰阴。
onMeasure方法最后需要調(diào)用setMeasuredDimension方法來(lái)保存測(cè)量的寬高值瘾敢。
題外話
例1中,發(fā)現(xiàn)在onMeasure()里最終確定寬高時(shí)調(diào)用setMeasuredDimension()尿这。
在onSizeChanged()中g(shù)etMeasuredWidth()/getMeasuredHeight()廉丽,get方法得到的數(shù)值應(yīng)該就是onMeasure()中set方法確定的。
// 點(diǎn)進(jìn)去看看源碼就知道了