A MeasureSpec encapsulates the layout requirements passed from parent to
child. Each MeasureSpec represents a requirement
for either the width or the height. A MeasureSpec is comprised of a size and
a mode. There are three possible modes:
- UNSPECIFIED
- The parent has not imposed any constraint on the child. It can be whatever
size it wants. - EXACTLY
- The parent has determined an exact size for the child. The child is going
to be given those bounds regardless of how big it wants to be. - AT_MOST
- The child can be as large as it wants up to the specified size.
1.使用 View.resolveSize(int
size,int measureSpec)
public static int resolveSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = size;
break;
case MeasureSpec.AT_MOST:
result = Math.min(size, specSize);
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
2.源码
public static class MeasureSpec {
private static final int MODE_SHIFT = 30;
private static final int MODE_MASK = 0x3 << MODE_SHIFT;public static final int UNSPECIFIED = 0 << MODE_SHIFT;
public static final int EXACTLY = 1 << MODE_SHIFT;
public static final int AT_MOST = 2 << MODE_SHIFT;
public static int makeMeasureSpec(int size, int mode) {
return size + mode;
}public static int getMode(int measureSpec) {
return (measureSpec & MODE_MASK);
}public static int getSize(int measureSpec) {
return (measureSpec & ~MODE_MASK);
}public static String toString(int measureSpec) {
int mode = getMode(measureSpec);
int size = getSize(measureSpec);StringBuilder sb = new StringBuilder("MeasureSpec: ");
if (mode == UNSPECIFIED)
sb.append("UNSPECIFIED ");
else if (mode == EXACTLY)
sb.append("EXACTLY ");
else if (mode == AT_MOST)
sb.append("AT_MOST ");
else
sb.append(mode).append(" ");sb.append(size);
return sb.toString();
}
}
3.示例ListView.measureItem(View
child)
private void measureItem(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null) {
p = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
android自定义View (一)MeasureSpec,布布扣,bubuko.com