void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) { LayoutParams lp; int totalLength; int childWidth; int childHeight; int childBaseline; int i; this.mTotalLength = SHOW_DIVIDER_NONE; int maxHeight = SHOW_DIVIDER_NONE; int childState = SHOW_DIVIDER_NONE; int alternativeMaxHeight = SHOW_DIVIDER_NONE; int weightedMaxHeight = SHOW_DIVIDER_NONE; boolean allFillParent = true; float totalWeight = 0.0f; int count = getVirtualChildCount(); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); boolean matchHeight = false; boolean skippedMeasure = false; if (this.mMaxAscent == null || this.mMaxDescent == null) { this.mMaxAscent = new int[VERTICAL_GRAVITY_COUNT]; this.mMaxDescent = new int[VERTICAL_GRAVITY_COUNT]; } int[] maxAscent = this.mMaxAscent; int[] maxDescent = this.mMaxDescent; maxAscent[INDEX_FILL] = -1; maxAscent[SHOW_DIVIDER_MIDDLE] = -1; maxAscent[VERTICAL] = -1; maxAscent[SHOW_DIVIDER_NONE] = -1; maxDescent[INDEX_FILL] = -1; maxDescent[SHOW_DIVIDER_MIDDLE] = -1; maxDescent[VERTICAL] = -1; maxDescent[SHOW_DIVIDER_NONE] = -1; boolean baselineAligned = this.mBaselineAligned; boolean useLargestChild = this.mUseLargestChild; boolean isExactly = widthMode == 1073741824; int largestChildWidth = RtlSpacingHelper.UNDEFINED; int i2 = SHOW_DIVIDER_NONE; while (i2 < count) { boolean matchHeightLocally; int margin; View child = getVirtualChildAt(i2); if (child == null) { this.mTotalLength += measureNullChild(i2); } else if (child.getVisibility() == 8) { i2 += getChildrenSkipCount(child, i2); } else { if (hasDividerBeforeChildAt(i2)) { this.mTotalLength += this.mDividerWidth; } lp = (LayoutParams) child.getLayoutParams(); totalWeight += lp.weight; if (widthMode == 1073741824 && lp.width == 0 && lp.weight > 0.0f) { if (isExactly) { this.mTotalLength += lp.leftMargin + lp.rightMargin; } else { totalLength = this.mTotalLength; this.mTotalLength = Math.max(totalLength, (lp.leftMargin + totalLength) + lp.rightMargin); } if (baselineAligned) { int freeSpec = MeasureSpec.makeMeasureSpec(SHOW_DIVIDER_NONE, SHOW_DIVIDER_NONE); child.measure(freeSpec, freeSpec); } else { skippedMeasure = true; } } else { int oldWidth = RtlSpacingHelper.UNDEFINED; if (lp.width == 0 && lp.weight > 0.0f) { oldWidth = SHOW_DIVIDER_NONE; lp.width = -2; } measureChildBeforeLayout( child, i2, widthMeasureSpec, totalWeight == 0.0f ? this.mTotalLength : SHOW_DIVIDER_NONE, heightMeasureSpec, SHOW_DIVIDER_NONE); if (oldWidth != Integer.MIN_VALUE) { lp.width = oldWidth; } childWidth = child.getMeasuredWidth(); if (isExactly) { this.mTotalLength += ((lp.leftMargin + childWidth) + lp.rightMargin) + getNextLocationOffset(child); } else { totalLength = this.mTotalLength; this.mTotalLength = Math.max( totalLength, (((totalLength + childWidth) + lp.leftMargin) + lp.rightMargin) + getNextLocationOffset(child)); } if (useLargestChild) { largestChildWidth = Math.max(childWidth, largestChildWidth); } } matchHeightLocally = false; if (heightMode != 1073741824 && lp.height == -1) { matchHeight = true; matchHeightLocally = true; } margin = lp.topMargin + lp.bottomMargin; childHeight = child.getMeasuredHeight() + margin; childState = View.combineMeasuredStates(childState, child.getMeasuredState()); if (baselineAligned) { childBaseline = child.getBaseline(); if (childBaseline != -1) { if (lp.gravity < 0) { i = this.mGravity; } else { i = lp.gravity; } int index = (((i & KeyEvent.KEYCODE_FORWARD_DEL) >> VERTICAL_GRAVITY_COUNT) & -2) >> VERTICAL; maxAscent[index] = Math.max(maxAscent[index], childBaseline); maxDescent[index] = Math.max(maxDescent[index], childHeight - childBaseline); } } maxHeight = Math.max(maxHeight, childHeight); allFillParent = allFillParent && lp.height == -1; if (lp.weight > 0.0f) { if (!matchHeightLocally) { margin = childHeight; } weightedMaxHeight = Math.max(weightedMaxHeight, margin); } else { if (!matchHeightLocally) { margin = childHeight; } alternativeMaxHeight = Math.max(alternativeMaxHeight, margin); } i2 += getChildrenSkipCount(child, i2); } i2 += VERTICAL; } if (this.mTotalLength > 0 && hasDividerBeforeChildAt(count)) { this.mTotalLength += this.mDividerWidth; } if (!(maxAscent[VERTICAL] == -1 && maxAscent[SHOW_DIVIDER_NONE] == -1 && maxAscent[SHOW_DIVIDER_MIDDLE] == -1 && maxAscent[INDEX_FILL] == -1)) { maxHeight = Math.max( maxHeight, Math.max( maxAscent[INDEX_FILL], Math.max( maxAscent[SHOW_DIVIDER_NONE], Math.max(maxAscent[VERTICAL], maxAscent[SHOW_DIVIDER_MIDDLE]))) + Math.max( maxDescent[INDEX_FILL], Math.max( maxDescent[SHOW_DIVIDER_NONE], Math.max(maxDescent[VERTICAL], maxDescent[SHOW_DIVIDER_MIDDLE])))); } if (useLargestChild && (widthMode == Integer.MIN_VALUE || widthMode == 0)) { this.mTotalLength = SHOW_DIVIDER_NONE; i2 = SHOW_DIVIDER_NONE; while (i2 < count) { child = getVirtualChildAt(i2); if (child == null) { this.mTotalLength += measureNullChild(i2); } else if (child.getVisibility() == 8) { i2 += getChildrenSkipCount(child, i2); } else { lp = (LayoutParams) child.getLayoutParams(); if (isExactly) { this.mTotalLength += ((lp.leftMargin + largestChildWidth) + lp.rightMargin) + getNextLocationOffset(child); } else { totalLength = this.mTotalLength; this.mTotalLength = Math.max( totalLength, (((totalLength + largestChildWidth) + lp.leftMargin) + lp.rightMargin) + getNextLocationOffset(child)); } } i2 += VERTICAL; } } this.mTotalLength += this.mPaddingLeft + this.mPaddingRight; int widthSizeAndState = View.resolveSizeAndState( Math.max(this.mTotalLength, getSuggestedMinimumWidth()), widthMeasureSpec, SHOW_DIVIDER_NONE); int delta = (widthSizeAndState & View.MEASURED_SIZE_MASK) - this.mTotalLength; if (skippedMeasure || (delta != 0 && totalWeight > 0.0f)) { float weightSum; if (this.mWeightSum > 0.0f) { weightSum = this.mWeightSum; } else { weightSum = totalWeight; } maxAscent[INDEX_FILL] = -1; maxAscent[SHOW_DIVIDER_MIDDLE] = -1; maxAscent[VERTICAL] = -1; maxAscent[SHOW_DIVIDER_NONE] = -1; maxDescent[INDEX_FILL] = -1; maxDescent[SHOW_DIVIDER_MIDDLE] = -1; maxDescent[VERTICAL] = -1; maxDescent[SHOW_DIVIDER_NONE] = -1; maxHeight = -1; this.mTotalLength = SHOW_DIVIDER_NONE; for (i2 = SHOW_DIVIDER_NONE; i2 < count; i2 += VERTICAL) { child = getVirtualChildAt(i2); if (!(child == null || child.getVisibility() == 8)) { lp = (LayoutParams) child.getLayoutParams(); float childExtra = lp.weight; if (childExtra > 0.0f) { int share = (int) ((((float) delta) * childExtra) / weightSum); weightSum -= childExtra; delta -= share; int childHeightMeasureSpec = ViewGroup.getChildMeasureSpec( heightMeasureSpec, ((this.mPaddingTop + this.mPaddingBottom) + lp.topMargin) + lp.bottomMargin, lp.height); if (lp.width == 0 && widthMode == 1073741824) { if (share <= 0) { share = SHOW_DIVIDER_NONE; } child.measure( MeasureSpec.makeMeasureSpec(share, EditorInfo.IME_FLAG_NO_ENTER_ACTION), childHeightMeasureSpec); } else { childWidth = child.getMeasuredWidth() + share; if (childWidth < 0) { childWidth = SHOW_DIVIDER_NONE; } child.measure( MeasureSpec.makeMeasureSpec(childWidth, EditorInfo.IME_FLAG_NO_ENTER_ACTION), childHeightMeasureSpec); } childState = View.combineMeasuredStates(childState, child.getMeasuredState() & Color.BLACK); } if (isExactly) { this.mTotalLength += ((child.getMeasuredWidth() + lp.leftMargin) + lp.rightMargin) + getNextLocationOffset(child); } else { totalLength = this.mTotalLength; this.mTotalLength = Math.max( totalLength, (((child.getMeasuredWidth() + totalLength) + lp.leftMargin) + lp.rightMargin) + getNextLocationOffset(child)); } matchHeightLocally = heightMode != 1073741824 && lp.height == -1; margin = lp.topMargin + lp.bottomMargin; childHeight = child.getMeasuredHeight() + margin; maxHeight = Math.max(maxHeight, childHeight); if (!matchHeightLocally) { margin = childHeight; } alternativeMaxHeight = Math.max(alternativeMaxHeight, margin); allFillParent = allFillParent && lp.height == -1; if (baselineAligned) { childBaseline = child.getBaseline(); if (childBaseline != -1) { if (lp.gravity < 0) { i = this.mGravity; } else { i = lp.gravity; } index = (((i & KeyEvent.KEYCODE_FORWARD_DEL) >> VERTICAL_GRAVITY_COUNT) & -2) >> VERTICAL; maxAscent[index] = Math.max(maxAscent[index], childBaseline); maxDescent[index] = Math.max(maxDescent[index], childHeight - childBaseline); } } } } this.mTotalLength += this.mPaddingLeft + this.mPaddingRight; if (!(maxAscent[VERTICAL] == -1 && maxAscent[SHOW_DIVIDER_NONE] == -1 && maxAscent[SHOW_DIVIDER_MIDDLE] == -1 && maxAscent[INDEX_FILL] == -1)) { maxHeight = Math.max( maxHeight, Math.max( maxAscent[INDEX_FILL], Math.max( maxAscent[SHOW_DIVIDER_NONE], Math.max(maxAscent[VERTICAL], maxAscent[SHOW_DIVIDER_MIDDLE]))) + Math.max( maxDescent[INDEX_FILL], Math.max( maxDescent[SHOW_DIVIDER_NONE], Math.max(maxDescent[VERTICAL], maxDescent[SHOW_DIVIDER_MIDDLE])))); } } else { alternativeMaxHeight = Math.max(alternativeMaxHeight, weightedMaxHeight); if (useLargestChild && widthMode != 1073741824) { for (i2 = SHOW_DIVIDER_NONE; i2 < count; i2 += VERTICAL) { child = getVirtualChildAt(i2); if (!(child == null || child.getVisibility() == 8)) { if (((LayoutParams) child.getLayoutParams()).weight > 0.0f) { child.measure( MeasureSpec.makeMeasureSpec( largestChildWidth, EditorInfo.IME_FLAG_NO_ENTER_ACTION), MeasureSpec.makeMeasureSpec( child.getMeasuredHeight(), EditorInfo.IME_FLAG_NO_ENTER_ACTION)); } } } } } if (!(allFillParent || heightMode == 1073741824)) { maxHeight = alternativeMaxHeight; } setMeasuredDimension( (Color.BLACK & childState) | widthSizeAndState, View.resolveSizeAndState( Math.max( maxHeight + (this.mPaddingTop + this.mPaddingBottom), getSuggestedMinimumHeight()), heightMeasureSpec, childState << 16)); if (matchHeight) { forceUniformHeight(count, widthMeasureSpec); } }
void measureVertical(int widthMeasureSpec, int heightMeasureSpec) { boolean matchWidthLocally; int measuredWidth; this.mTotalLength = SHOW_DIVIDER_NONE; int maxWidth = SHOW_DIVIDER_NONE; int childState = SHOW_DIVIDER_NONE; int alternativeMaxWidth = SHOW_DIVIDER_NONE; int weightedMaxWidth = SHOW_DIVIDER_NONE; boolean allFillParent = true; float totalWeight = 0.0f; int count = getVirtualChildCount(); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); boolean matchWidth = false; boolean skippedMeasure = false; int baselineChildIndex = this.mBaselineAlignedChildIndex; boolean useLargestChild = this.mUseLargestChild; int largestChildHeight = RtlSpacingHelper.UNDEFINED; int i = SHOW_DIVIDER_NONE; while (i < count) { LayoutParams lp; int totalLength; int childHeight; int margin; View child = getVirtualChildAt(i); if (child == null) { this.mTotalLength += measureNullChild(i); } else if (child.getVisibility() == 8) { i += getChildrenSkipCount(child, i); } else { if (hasDividerBeforeChildAt(i)) { this.mTotalLength += this.mDividerHeight; } lp = (LayoutParams) child.getLayoutParams(); totalWeight += lp.weight; if (heightMode == 1073741824 && lp.height == 0 && lp.weight > 0.0f) { totalLength = this.mTotalLength; this.mTotalLength = Math.max(totalLength, (lp.topMargin + totalLength) + lp.bottomMargin); skippedMeasure = true; } else { int oldHeight = RtlSpacingHelper.UNDEFINED; if (lp.height == 0 && lp.weight > 0.0f) { oldHeight = SHOW_DIVIDER_NONE; lp.height = -2; } measureChildBeforeLayout( child, i, widthMeasureSpec, SHOW_DIVIDER_NONE, heightMeasureSpec, totalWeight == 0.0f ? this.mTotalLength : SHOW_DIVIDER_NONE); if (oldHeight != Integer.MIN_VALUE) { lp.height = oldHeight; } childHeight = child.getMeasuredHeight(); totalLength = this.mTotalLength; this.mTotalLength = Math.max( totalLength, (((totalLength + childHeight) + lp.topMargin) + lp.bottomMargin) + getNextLocationOffset(child)); if (useLargestChild) { largestChildHeight = Math.max(childHeight, largestChildHeight); } } if (baselineChildIndex >= 0 && baselineChildIndex == i + VERTICAL) { this.mBaselineChildTop = this.mTotalLength; } if (i >= baselineChildIndex || lp.weight <= 0.0f) { matchWidthLocally = false; if (widthMode != 1073741824 && lp.width == -1) { matchWidth = true; matchWidthLocally = true; } margin = lp.leftMargin + lp.rightMargin; measuredWidth = child.getMeasuredWidth() + margin; maxWidth = Math.max(maxWidth, measuredWidth); childState = View.combineMeasuredStates(childState, child.getMeasuredState()); allFillParent = allFillParent && lp.width == -1; if (lp.weight > 0.0f) { if (!matchWidthLocally) { margin = measuredWidth; } weightedMaxWidth = Math.max(weightedMaxWidth, margin); } else { if (!matchWidthLocally) { margin = measuredWidth; } alternativeMaxWidth = Math.max(alternativeMaxWidth, margin); } i += getChildrenSkipCount(child, i); } else { throw new RuntimeException( "A child of LinearLayout with index less than mBaselineAlignedChildIndex has weight > 0, which won't work. Either remove the weight, or don't set mBaselineAlignedChildIndex."); } } i += VERTICAL; } if (this.mTotalLength > 0 && hasDividerBeforeChildAt(count)) { this.mTotalLength += this.mDividerHeight; } if (useLargestChild && (heightMode == Integer.MIN_VALUE || heightMode == 0)) { this.mTotalLength = SHOW_DIVIDER_NONE; i = SHOW_DIVIDER_NONE; while (i < count) { child = getVirtualChildAt(i); if (child == null) { this.mTotalLength += measureNullChild(i); } else if (child.getVisibility() == 8) { i += getChildrenSkipCount(child, i); } else { lp = (LayoutParams) child.getLayoutParams(); totalLength = this.mTotalLength; this.mTotalLength = Math.max( totalLength, (((totalLength + largestChildHeight) + lp.topMargin) + lp.bottomMargin) + getNextLocationOffset(child)); } i += VERTICAL; } } this.mTotalLength += this.mPaddingTop + this.mPaddingBottom; int heightSizeAndState = View.resolveSizeAndState( Math.max(this.mTotalLength, getSuggestedMinimumHeight()), heightMeasureSpec, SHOW_DIVIDER_NONE); int delta = (heightSizeAndState & View.MEASURED_SIZE_MASK) - this.mTotalLength; if (skippedMeasure || (delta != 0 && totalWeight > 0.0f)) { float weightSum; if (this.mWeightSum > 0.0f) { weightSum = this.mWeightSum; } else { weightSum = totalWeight; } this.mTotalLength = SHOW_DIVIDER_NONE; for (i = SHOW_DIVIDER_NONE; i < count; i += VERTICAL) { child = getVirtualChildAt(i); if (child.getVisibility() != 8) { lp = (LayoutParams) child.getLayoutParams(); float childExtra = lp.weight; if (childExtra > 0.0f) { int share = (int) ((((float) delta) * childExtra) / weightSum); weightSum -= childExtra; delta -= share; int childWidthMeasureSpec = ViewGroup.getChildMeasureSpec( widthMeasureSpec, ((this.mPaddingLeft + this.mPaddingRight) + lp.leftMargin) + lp.rightMargin, lp.width); if (lp.height == 0 && heightMode == 1073741824) { if (share <= 0) { share = SHOW_DIVIDER_NONE; } child.measure( childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(share, EditorInfo.IME_FLAG_NO_ENTER_ACTION)); } else { childHeight = child.getMeasuredHeight() + share; if (childHeight < 0) { childHeight = SHOW_DIVIDER_NONE; } child.measure( childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(childHeight, EditorInfo.IME_FLAG_NO_ENTER_ACTION)); } childState = View.combineMeasuredStates( childState, child.getMeasuredState() & InputDevice.SOURCE_ANY); } margin = lp.leftMargin + lp.rightMargin; measuredWidth = child.getMeasuredWidth() + margin; maxWidth = Math.max(maxWidth, measuredWidth); matchWidthLocally = widthMode != 1073741824 && lp.width == -1; if (!matchWidthLocally) { margin = measuredWidth; } alternativeMaxWidth = Math.max(alternativeMaxWidth, margin); allFillParent = allFillParent && lp.width == -1; totalLength = this.mTotalLength; this.mTotalLength = Math.max( totalLength, (((child.getMeasuredHeight() + totalLength) + lp.topMargin) + lp.bottomMargin) + getNextLocationOffset(child)); } } this.mTotalLength += this.mPaddingTop + this.mPaddingBottom; } else { alternativeMaxWidth = Math.max(alternativeMaxWidth, weightedMaxWidth); if (useLargestChild && heightMode != 1073741824) { for (i = SHOW_DIVIDER_NONE; i < count; i += VERTICAL) { child = getVirtualChildAt(i); if (!(child == null || child.getVisibility() == 8)) { if (((LayoutParams) child.getLayoutParams()).weight > 0.0f) { child.measure( MeasureSpec.makeMeasureSpec( child.getMeasuredWidth(), EditorInfo.IME_FLAG_NO_ENTER_ACTION), MeasureSpec.makeMeasureSpec( largestChildHeight, EditorInfo.IME_FLAG_NO_ENTER_ACTION)); } } } } } if (!(allFillParent || widthMode == 1073741824)) { maxWidth = alternativeMaxWidth; } setMeasuredDimension( View.resolveSizeAndState( Math.max( maxWidth + (this.mPaddingLeft + this.mPaddingRight), getSuggestedMinimumWidth()), widthMeasureSpec, childState), heightSizeAndState); if (matchWidth) { forceUniformWidth(count, heightMeasureSpec); } }
public static int resolveSizeAndState(int i, int i2, int i3) { return View.resolveSizeAndState(i, i2, i3); }
public static int resolveSizeAndState(int i, int j, int k) { return View.resolveSizeAndState(i, j, k); }
public static int a(int paramInt1, int paramInt2, int paramInt3) { return View.resolveSizeAndState(paramInt1, paramInt2, paramInt3); }