下面列出了android.support.v4.view.ViewCompat#resolveSizeAndState ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int minWidth = getSuggestedMinimumWidth() + getPaddingLeft() + getPaddingRight();
int width = ViewCompat.resolveSizeAndState(minWidth, widthMeasureSpec, 1);
int minHeight = MeasureSpec.getSize(width) + getPaddingBottom() + getPaddingTop();
int height = ViewCompat.resolveSizeAndState(minHeight, heightMeasureSpec, 0);
selectorRadius = height / 2;
enabledSelectorCenter.set(width - selectorRadius, height / 2);
disabledSelectorCenter.set(selectorRadius, height / 2);
if (isChecked()) {
currentSelectorCenter.set(disabledSelectorCenter.x, disabledSelectorCenter.y);
} else {
currentSelectorCenter.set(enabledSelectorCenter.x, enabledSelectorCenter.y);
}
int borderPadding = BORDER_WIDTH / 2;
backgroundRect.set(borderPadding, borderPadding, width - borderPadding,
height - borderPadding);
setMeasuredDimension(width, height);
}
@SuppressWarnings("SuspiciousNameCombination")
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
int requiredWidth = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
int requiredHeight = getPaddingBottom() + getPaddingTop() + getSuggestedMinimumHeight();
requiredWidth = ViewCompat.resolveSizeAndState(
requiredWidth,
widthMeasureSpec,
0
);
requiredHeight = ViewCompat.resolveSizeAndState(
requiredHeight,
heightMeasureSpec,
0
);
/* If it's required to be a circle, set both height & width to be the
* minimum of the two.
* */
if (mFullCircle) {
if (requiredHeight > requiredWidth) {
setMeasuredDimension(requiredWidth, requiredWidth);
} else {
setMeasuredDimension(requiredHeight, requiredHeight);
}
} else {
setMeasuredDimension(requiredWidth, requiredHeight);
}
}
private void setMeasuredDimensionForFlex(@FlexDirection int flexDirection, int widthMeasureSpec,
int heightMeasureSpec, int childState) {
int widthMode = View.MeasureSpec.getMode(widthMeasureSpec);
int widthSize = View.MeasureSpec.getSize(widthMeasureSpec);
int heightMode = View.MeasureSpec.getMode(heightMeasureSpec);
int heightSize = View.MeasureSpec.getSize(heightMeasureSpec);
int calculatedMaxHeight;
int calculatedMaxWidth;
switch (flexDirection) {
case FLEX_DIRECTION_ROW: // Intentional fall through
case FLEX_DIRECTION_ROW_REVERSE:
calculatedMaxHeight = getSumOfCrossSize() + getComPaddingTop()
+ getComPaddingBottom();
calculatedMaxWidth = getLargestMainSize();
break;
case FLEX_DIRECTION_COLUMN: // Intentional fall through
case FLEX_DIRECTION_COLUMN_REVERSE:
calculatedMaxHeight = getLargestMainSize();
calculatedMaxWidth = getSumOfCrossSize() + getComPaddingLeft() + getComPaddingRight();
break;
default:
throw new IllegalArgumentException("Invalid flex direction: " + flexDirection);
}
int widthSizeAndState;
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
if (widthSize < calculatedMaxWidth) {
childState = ViewCompat
.combineMeasuredStates(childState, ViewCompat.MEASURED_STATE_TOO_SMALL);
}
widthSizeAndState = ViewCompat.resolveSizeAndState(widthSize, widthMeasureSpec,
childState);
break;
case View.MeasureSpec.AT_MOST: {
if (widthSize < calculatedMaxWidth) {
childState = ViewCompat
.combineMeasuredStates(childState, ViewCompat.MEASURED_STATE_TOO_SMALL);
} else {
widthSize = calculatedMaxWidth;
}
widthSizeAndState = ViewCompat.resolveSizeAndState(widthSize, widthMeasureSpec,
childState);
break;
}
case View.MeasureSpec.UNSPECIFIED: {
widthSizeAndState = ViewCompat
.resolveSizeAndState(calculatedMaxWidth, widthMeasureSpec, childState);
break;
}
default:
throw new IllegalStateException("Unknown width mode is set: " + widthMode);
}
int heightSizeAndState;
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
if (heightSize < calculatedMaxHeight) {
childState = ViewCompat.combineMeasuredStates(childState,
ViewCompat.MEASURED_STATE_TOO_SMALL
>> ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
}
heightSizeAndState = ViewCompat.resolveSizeAndState(heightSize, heightMeasureSpec,
childState);
break;
case View.MeasureSpec.AT_MOST: {
if (heightSize < calculatedMaxHeight) {
childState = ViewCompat.combineMeasuredStates(childState,
ViewCompat.MEASURED_STATE_TOO_SMALL
>> ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
} else {
heightSize = calculatedMaxHeight;
}
heightSizeAndState = ViewCompat.resolveSizeAndState(heightSize, heightMeasureSpec,
childState);
break;
}
case View.MeasureSpec.UNSPECIFIED: {
heightSizeAndState = ViewCompat.resolveSizeAndState(calculatedMaxHeight,
heightMeasureSpec, childState);
break;
}
default:
throw new IllegalStateException("Unknown height mode is set: " + heightMode);
}
setComMeasuredDimension(widthSizeAndState, heightSizeAndState);
}
/**
* Set this FlexboxLayouts' width and height depending on the calculated size of main axis and
* cross axis.
*
* @param flexDirection the value of the flex direction
* @param widthMeasureSpec horizontal space requirements as imposed by the parent
* @param heightMeasureSpec vertical space requirements as imposed by the parent
* @param childState the child state of the View
* @see #getFlexDirection()
* @see #setFlexDirection(int)
*/
private void setMeasuredDimensionForFlex(@FlexDirection int flexDirection, int widthMeasureSpec,
int heightMeasureSpec, int childState) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int calculatedMaxHeight;
int calculatedMaxWidth;
switch (flexDirection) {
case FLEX_DIRECTION_ROW: // Intentional fall through
case FLEX_DIRECTION_ROW_REVERSE:
calculatedMaxHeight = getSumOfCrossSize() + getPaddingTop()
+ getPaddingBottom();
calculatedMaxWidth = getLargestMainSize();
break;
case FLEX_DIRECTION_COLUMN: // Intentional fall through
case FLEX_DIRECTION_COLUMN_REVERSE:
calculatedMaxHeight = getLargestMainSize();
calculatedMaxWidth = getSumOfCrossSize() + getPaddingLeft() + getPaddingRight();
break;
default:
throw new IllegalArgumentException("Invalid flex direction: " + flexDirection);
}
int widthSizeAndState;
switch (widthMode) {
case MeasureSpec.EXACTLY:
if (widthSize < calculatedMaxWidth) {
childState = ViewCompat
.combineMeasuredStates(childState, ViewCompat.MEASURED_STATE_TOO_SMALL);
}
widthSizeAndState = ViewCompat.resolveSizeAndState(widthSize, widthMeasureSpec,
childState);
break;
case MeasureSpec.AT_MOST: {
if (widthSize < calculatedMaxWidth) {
childState = ViewCompat
.combineMeasuredStates(childState, ViewCompat.MEASURED_STATE_TOO_SMALL);
} else {
widthSize = calculatedMaxWidth;
}
widthSizeAndState = ViewCompat.resolveSizeAndState(widthSize, widthMeasureSpec,
childState);
break;
}
case MeasureSpec.UNSPECIFIED: {
widthSizeAndState = ViewCompat
.resolveSizeAndState(calculatedMaxWidth, widthMeasureSpec, childState);
break;
}
default:
throw new IllegalStateException("Unknown width mode is set: " + widthMode);
}
int heightSizeAndState;
switch (heightMode) {
case MeasureSpec.EXACTLY:
if (heightSize < calculatedMaxHeight) {
childState = ViewCompat.combineMeasuredStates(childState,
ViewCompat.MEASURED_STATE_TOO_SMALL
>> ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
}
heightSizeAndState = ViewCompat.resolveSizeAndState(heightSize, heightMeasureSpec,
childState);
break;
case MeasureSpec.AT_MOST: {
if (heightSize < calculatedMaxHeight) {
childState = ViewCompat.combineMeasuredStates(childState,
ViewCompat.MEASURED_STATE_TOO_SMALL
>> ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
} else {
heightSize = calculatedMaxHeight;
}
heightSizeAndState = ViewCompat.resolveSizeAndState(heightSize, heightMeasureSpec,
childState);
break;
}
case MeasureSpec.UNSPECIFIED: {
heightSizeAndState = ViewCompat.resolveSizeAndState(calculatedMaxHeight,
heightMeasureSpec, childState);
break;
}
default:
throw new IllegalStateException("Unknown height mode is set: " + heightMode);
}
setMeasuredDimension(widthSizeAndState, heightSizeAndState);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
prepareChildren();
ensurePreDrawListener();
final int paddingLeft = getPaddingLeft();
final int paddingTop = getPaddingTop();
final int paddingRight = getPaddingRight();
final int paddingBottom = getPaddingBottom();
final int layoutDirection = ViewCompat.getLayoutDirection(this);
final boolean isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
final int widthPadding = paddingLeft + paddingRight;
final int heightPadding = paddingTop + paddingBottom;
int widthUsed = getSuggestedMinimumWidth();
int heightUsed = getSuggestedMinimumHeight();
int childState = 0;
final boolean applyInsets = mLastInsets != null && ViewCompat.getFitsSystemWindows(this);
final int childCount = mDependencySortedChildren.size();
for (int i = 0; i < childCount; i++) {
final View child = mDependencySortedChildren.get(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
int keylineWidthUsed = 0;
if (lp.keyline >= 0 && widthMode != MeasureSpec.UNSPECIFIED) {
final int keylinePos = getKeyline(lp.keyline);
final int keylineGravity = GravityCompat.getAbsoluteGravity(
resolveKeylineGravity(lp.gravity), layoutDirection)
& Gravity.HORIZONTAL_GRAVITY_MASK;
if ((keylineGravity == Gravity.LEFT && !isRtl)
|| (keylineGravity == Gravity.RIGHT && isRtl)) {
keylineWidthUsed = Math.max(0, widthSize - paddingRight - keylinePos);
} else if ((keylineGravity == Gravity.RIGHT && !isRtl)
|| (keylineGravity == Gravity.LEFT && isRtl)) {
keylineWidthUsed = Math.max(0, keylinePos - paddingLeft);
}
}
int childWidthMeasureSpec = widthMeasureSpec;
int childHeightMeasureSpec = heightMeasureSpec;
if (applyInsets && !ViewCompat.getFitsSystemWindows(child)) {
// We're set to handle insets but this child isn't, so we will measure the
// child as if there are no insets
final int horizInsets = mLastInsets.getSystemWindowInsetLeft()
+ mLastInsets.getSystemWindowInsetRight();
final int vertInsets = mLastInsets.getSystemWindowInsetTop()
+ mLastInsets.getSystemWindowInsetBottom();
childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
widthSize - horizInsets, widthMode);
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
heightSize - vertInsets, heightMode);
}
final Behavior b = lp.getBehavior();
if (b == null || !b.onMeasureChild(this, child, childWidthMeasureSpec, keylineWidthUsed,
childHeightMeasureSpec, 0)) {
onMeasureChild(child, childWidthMeasureSpec, keylineWidthUsed,
childHeightMeasureSpec, 0);
}
widthUsed = Math.max(widthUsed, widthPadding + child.getMeasuredWidth() +
lp.leftMargin + lp.rightMargin);
heightUsed = Math.max(heightUsed, heightPadding + child.getMeasuredHeight() +
lp.topMargin + lp.bottomMargin);
childState = ViewCompat.combineMeasuredStates(childState,
ViewCompat.getMeasuredState(child));
}
final int width = ViewCompat.resolveSizeAndState(widthUsed, widthMeasureSpec,
childState & ViewCompat.MEASURED_STATE_MASK);
final int height = ViewCompat.resolveSizeAndState(heightUsed, heightMeasureSpec,
childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
setMeasuredDimension(width, height);
}
/**
* Set this FlexboxLayouts' width and height depending on the calculated size of main axis and
* cross axis.
*
* @param flexDirection the value of the flex direction
* @param widthMeasureSpec horizontal space requirements as imposed by the parent
* @param heightMeasureSpec vertical space requirements as imposed by the parent
* @param childState the child state of the View
* @see #getFlexDirection()
* @see #setFlexDirection(int)
*/
private void setMeasuredDimensionForFlex(@FlexDirection int flexDirection, int widthMeasureSpec,
int heightMeasureSpec, int childState) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int calculatedMaxHeight;
int calculatedMaxWidth;
switch (flexDirection) {
case FLEX_DIRECTION_ROW: // Intentional fall through
case FLEX_DIRECTION_ROW_REVERSE:
calculatedMaxHeight = getSumOfCrossSize() + getPaddingTop()
+ getPaddingBottom();
calculatedMaxWidth = getLargestMainSize();
break;
case FLEX_DIRECTION_COLUMN: // Intentional fall through
case FLEX_DIRECTION_COLUMN_REVERSE:
calculatedMaxHeight = getLargestMainSize();
calculatedMaxWidth = getSumOfCrossSize() + getPaddingLeft() + getPaddingRight();
break;
default:
throw new IllegalArgumentException("Invalid flex direction: " + flexDirection);
}
int widthSizeAndState;
switch (widthMode) {
case MeasureSpec.EXACTLY:
if (widthSize < calculatedMaxWidth) {
childState = ViewCompat
.combineMeasuredStates(childState, ViewCompat.MEASURED_STATE_TOO_SMALL);
}
widthSizeAndState = ViewCompat.resolveSizeAndState(widthSize, widthMeasureSpec,
childState);
break;
case MeasureSpec.AT_MOST: {
if (widthSize < calculatedMaxWidth) {
childState = ViewCompat
.combineMeasuredStates(childState, ViewCompat.MEASURED_STATE_TOO_SMALL);
} else {
widthSize = calculatedMaxWidth;
}
widthSizeAndState = ViewCompat.resolveSizeAndState(widthSize, widthMeasureSpec,
childState);
break;
}
case MeasureSpec.UNSPECIFIED: {
widthSizeAndState = ViewCompat
.resolveSizeAndState(calculatedMaxWidth, widthMeasureSpec, childState);
break;
}
default:
throw new IllegalStateException("Unknown width mode is set: " + widthMode);
}
int heightSizeAndState;
switch (heightMode) {
case MeasureSpec.EXACTLY:
if (heightSize < calculatedMaxHeight) {
childState = ViewCompat.combineMeasuredStates(childState,
ViewCompat.MEASURED_STATE_TOO_SMALL
>> ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
}
heightSizeAndState = ViewCompat.resolveSizeAndState(heightSize, heightMeasureSpec,
childState);
break;
case MeasureSpec.AT_MOST: {
if (heightSize < calculatedMaxHeight) {
childState = ViewCompat.combineMeasuredStates(childState,
ViewCompat.MEASURED_STATE_TOO_SMALL
>> ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
} else {
heightSize = calculatedMaxHeight;
}
heightSizeAndState = ViewCompat.resolveSizeAndState(heightSize, heightMeasureSpec,
childState);
break;
}
case MeasureSpec.UNSPECIFIED: {
heightSizeAndState = ViewCompat.resolveSizeAndState(calculatedMaxHeight,
heightMeasureSpec, childState);
break;
}
default:
throw new IllegalStateException("Unknown height mode is set: " + heightMode);
}
setMeasuredDimension(widthSizeAndState, heightSizeAndState);
}