測量逝段,賦值颊糜,繪制
- 測量:父view調(diào)用子view的onMeasure()方法嗅剖,首先看子view是一個view還是viewgroup, 如果子view是一個view,直接調(diào)用它的onMeasure方法去測量范删,并把測量結(jié)果返回給父view根蟹。如果子view是一個viewgroup, 分別測量每個子view脓杉,保存每個子view的尺寸,并且計算并保存自己的尺寸简逮。
1.測量已有view的尺寸
public class MyImageView extends android.support.v7.widget.AppCompatImageView {
public MyImageView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
if (width > height) {
width = height;
} else {
height = width;
}
setMeasuredDimension(width, height);
}
}
2.測量自定義view的尺寸
public class CustomView extends ViewGroup {
public CustomView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getMeasuredWidth();
int height = getMeasuredHeight();
width = resolveSize(width, widthMeasureSpec);
height = resolveSize(height, heightMeasureSpec);
setMeasuredDimension(width, height);
}
public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
final int specMode = MeasureSpec.getMode(measureSpec);
final int specSize = MeasureSpec.getSize(measureSpec);
final int result;
switch (specMode) {
case MeasureSpec.AT_MOST:
if (specSize < size) {
result = specSize | MEASURED_STATE_TOO_SMALL;
} else {
result = size;
}
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
case MeasureSpec.UNSPECIFIED:
default:
result = size;
}
return result | (childMeasuredState & MEASURED_STATE_MASK);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
}
3.測量與布局自定義view
public class MyView extends ViewGroup {
public MyView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int viewCount = getChildCount();
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
for (int i = 0; i < viewCount; i++) {
View view = getChildAt(i);
LayoutParams lp = view.getLayoutParams();
int childMeasureSpec;
switch (lp.width) {
case LayoutParams.MATCH_PARENT:
if(widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST){
childMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize - 10, MeasureSpec.EXACTLY);
}else {
childMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
break;
case LayoutParams.WRAP_CONTENT:
if(widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST){
childMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize- 10 , MeasureSpec.AT_MOST);
}else{
childMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
default:
childMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
break;
}
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int viewCount = getChildCount();
for(int i=0; i<viewCount; i++){
View view = getChildAt(i);
view.layout(getLeft(), getTop(), getRight(), getBottom());
}
}
}