private void a(View paramView, boolean paramBoolean) { ViewGroup.LayoutParams localLayoutParams2 = paramView.getLayoutParams(); ViewGroup.LayoutParams localLayoutParams1 = localLayoutParams2; if (localLayoutParams2 == null) { localLayoutParams1 = generateDefaultLayoutParams(); } if (paramBoolean) { addViewInLayout(paramView, 0, localLayoutParams1); } paramView.setSelected(hasFocus()); if (this.A) { paramView.setEnabled(isEnabled()); } int i = ViewGroup.getChildMeasureSpec( this.b, this.d.top + this.d.bottom, localLayoutParams1.height); paramView.measure( ViewGroup.getChildMeasureSpec(this.c, this.d.left + this.d.right, localLayoutParams1.width), i); i = this.d.top + (getMeasuredHeight() - this.d.bottom - this.d.top - paramView.getMeasuredHeight()) / 2; int j = paramView.getMeasuredHeight(); paramView.layout(0, i, paramView.getMeasuredWidth() + 0, j + i); }
@Override public void onMeasure( RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { View view = null; if (state.getItemCount() > 0) { view = recycler.getViewForPosition(0); } int height = 0; int width = 0; if (view != null) { RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec( widthSpec, getPaddingLeft() + getPaddingRight(), params.width); int childHeightSpec = ViewGroup.getChildMeasureSpec( heightSpec, getPaddingTop() + getPaddingBottom(), params.height); view.measure(childWidthSpec, childHeightSpec); width = view.getMeasuredWidth() + params.leftMargin + params.rightMargin; height = view.getMeasuredHeight() + params.bottomMargin + params.topMargin; recycler.recycleView(view); } setMeasuredDimension(width, height); }
private void measureScrapChild( RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { try { View view = recycler.getViewForPosition(0); // fix 动态添加时报IndexOutOfBoundsException if (view != null) { RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec( heightSpec, getPaddingTop() + getPaddingBottom(), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } finally { } }
protected void constrainChild(View child, int width, int wMode, int height, int hMode) { LayoutParams p = (LayoutParams) child.getLayoutParams(); int childDimension = LayoutParams.WRAP_CONTENT; if (p.optionWidth != NOT_SET) { childDimension = p.optionWidth; } else { if (p.autoWidth && p.autoFillsWidth) { childDimension = LayoutParams.FILL_PARENT; } } int widthPadding = getViewWidthPadding(child); int widthSpec = ViewGroup.getChildMeasureSpec( MeasureSpec.makeMeasureSpec(width, wMode), widthPadding, childDimension); childDimension = LayoutParams.WRAP_CONTENT; if (p.optionHeight != NOT_SET) { childDimension = p.optionHeight; } else { if (p.autoHeight && p.autoFillsHeight && !vertical) { childDimension = LayoutParams.FILL_PARENT; } } int heightPadding = getViewHeightPadding(child); int heightSpec = ViewGroup.getChildMeasureSpec( MeasureSpec.makeMeasureSpec(height, hMode), heightPadding, childDimension); child.measure(widthSpec, heightSpec); // Useful for debugging. // int childWidth = child.getMeasuredWidth(); // int childHeight = child.getMeasuredHeight(); }
private void measureScrapChild( RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { // 挨个遍历所有item if (position < getItemCount()) { try { View view = recycler.getViewForPosition(position); // fix 动态添加时报IndexOutOfBoundsException if (view != null) { RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec( widthSpec, getPaddingLeft() + getPaddingRight(), lp.width); int childHeightSpec = ViewGroup.getChildMeasureSpec( heightSpec, getPaddingTop() + getPaddingBottom(), lp.height); // 子view进行测量,然后可以通过getMeasuredWidth()获得测量的宽,高类似 view.measure(childWidthSpec, childHeightSpec); // 将item的宽高放入数组中 measuredDimension[0] = view.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } } }
private void measureScrapChild( RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { if (position < getItemCount()) { try { View view = recycler.getViewForPosition(position); // fix 动态添加时报IndexOutOfBoundsException if (view.getVisibility() == View.GONE) { measuredDimension[0] = 0; measuredDimension[1] = 0; return; } RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); // For adding Item Decor Insets to view super.measureChildWithMargins(view, 0, 0); /* 全部 0 final int l = getLeftDecorationWidth(view); final int r = getRightDecorationWidth(view); final int t = getTopDecorationHeight(view); final int b = getBottomDecorationHeight(view); System.out.println("measureScrapChild Decoration [ position_"+position+"]: left = " + l +" ,right = " + r +" ,top = " + t +" ,bottom = " + b);*/ // measureChild(view, widthSpec, heightSpec); // measureChildWithMargins(view,0,0); int childWidthSpec = ViewGroup.getChildMeasureSpec( widthSpec, getPaddingLeft() + getPaddingRight() + getLeftDecorationWidth(view) + getRightDecorationWidth(view), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec( heightSpec, getPaddingTop() + getPaddingBottom() + getTopDecorationHeight(view) + getBottomDecorationHeight(view), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin; measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin; // measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; // measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } catch (Exception e) { e.printStackTrace(); } } }
private void measureScrapChild(View child, int position, int widthMeasureSpec) { ListView.LayoutParams p = (ListView.LayoutParams) child.getLayoutParams(); if (p == null) { p = new ListView.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 0); child.setLayoutParams(p); } // XXX p.viewType = mAdapter.getItemViewType(position); // XXX p.forceAdd = true; int childWidthSpec = ViewGroup.getChildMeasureSpec( widthMeasureSpec, mDropDownList.getPaddingLeft() + mDropDownList.getPaddingRight(), 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); }
private void setUpChild(View child, int offset, int x, boolean fromLeft) { // Respect layout params that are already in the view. Otherwise // make some up... LayoutParams lp = child.getLayoutParams(); if (lp == null) { lp = (LayoutParams) generateDefaultLayoutParams(); } addViewInLayout(child, fromLeft ? -1 : 0, lp); if (mAllowChildSelection) { // final boolean wantfocus = offset == 0; // child.setSelected( wantfocus ); // if( wantfocus ){ // child.requestFocus(); // } } // Get measure specs int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, mPaddingTop + mPaddingBottom, lp.height); int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, mPaddingLeft + mPaddingRight, lp.width); // Measure child child.measure(childWidthSpec, childHeightSpec); int childLeft; int childRight; // Position vertically based on gravity setting int childTop = calculateTop(child, true); int childBottom = childTop + child.getMeasuredHeight(); int width = child.getMeasuredWidth(); if (fromLeft) { childLeft = x; childRight = childLeft + width; } else { childLeft = x - width; childRight = x; } child.layout(childLeft, childTop, childRight, childBottom); }
/** * Helper for makeAndAddView to set the position of a view and fill out its layout parameters. * * @param child The view to position * @param offset Offset from the selected position * @param x X-coordinate indicating where this view should be placed. This will either be the left * or right edge of the view, depending on the fromLeft parameter * @param fromLeft Are we positioning views based on the left edge? (i.e., building from left to * right)? */ private void setUpChild(final View child, final int offset, final int x, final boolean fromLeft) { /* * Respect layout params that are already in the view. Otherwise * make some up... */ LeftGallery.LayoutParams lp = child.getLayoutParams(); if (lp == null) { lp = generateDefaultLayoutParams(); } // CHECKSTYLE:OFF unmodified addViewInLayout(child, fromLeft != mIsRtl ? -1 : 0, lp); // CHECKSTYLE:ON child.setSelected(offset == 0); // Get measure specs final int childHeightSpec = ViewGroup.getChildMeasureSpec( mHeightMeasureSpec, mSpinnerPadding.top + mSpinnerPadding.bottom, lp.height); final int childWidthSpec = ViewGroup.getChildMeasureSpec( mWidthMeasureSpec, mSpinnerPadding.left + mSpinnerPadding.right, lp.width); // Measure child child.measure(childWidthSpec, childHeightSpec); int childLeft; int childRight; // Position vertically based on gravity setting final int childTop = calculateTop(child, true); final int childBottom = childTop + child.getMeasuredHeight(); final int width = child.getMeasuredWidth(); if (fromLeft) { childLeft = x; childRight = childLeft + width; } else { childLeft = x - width; childRight = x; } child.layout(childLeft, childTop, childRight, childBottom); }
@Override public View getHeader(RecyclerView parent, int position) { long headerId = mAdapter.getHeaderId(position); View header = mHeaderViews.get(headerId); if (header == null) { // TODO - recycle views RecyclerView.ViewHolder viewHolder = mAdapter.onCreateHeaderViewHolder(parent); mAdapter.onBindHeaderViewHolder(viewHolder, position); header = viewHolder.itemView; if (header.getLayoutParams() == null) { header.setLayoutParams( new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } int widthSpec; int heightSpec; if (mOrientationProvider.getOrientation(parent) == LinearLayoutManager.VERTICAL) { widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY); heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.UNSPECIFIED); } else { widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.UNSPECIFIED); heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.EXACTLY); } int childWidth = ViewGroup.getChildMeasureSpec( widthSpec, parent.getPaddingLeft() + parent.getPaddingRight(), header.getLayoutParams().width); int childHeight = ViewGroup.getChildMeasureSpec( heightSpec, parent.getPaddingTop() + parent.getPaddingBottom(), header.getLayoutParams().height); header.measure(childWidth, childHeight); header.layout(0, 0, header.getMeasuredWidth(), header.getMeasuredHeight()); mHeaderViews.put(headerId, header); } return header; }
/** * Helper for makeAndAddView to set the position of a view and fill out its layout paramters. * * @param child The view to position */ private void setUpChild(View child) { // Respect layout params that are already in the view. Otherwise // make some up... ViewGroup.LayoutParams lp = child.getLayoutParams(); if (lp == null) { lp = generateDefaultLayoutParams(); } addViewInLayout(child, 0, lp); child.setSelected(hasFocus()); // Get measure specs int childHeightSpec = ViewGroup.getChildMeasureSpec( mHeightMeasureSpec, mSpinnerPadding.top + mSpinnerPadding.bottom, lp.height); int childWidthSpec = ViewGroup.getChildMeasureSpec( mWidthMeasureSpec, mSpinnerPadding.left + mSpinnerPadding.right, lp.width); // Measure child child.measure(childWidthSpec, childHeightSpec); int childLeft; int childRight; // Position vertically based on gravity setting int childTop = mSpinnerPadding.top + ((mMeasuredHeight - mSpinnerPadding.bottom - mSpinnerPadding.top - child.getMeasuredHeight()) / 2); int childBottom = childTop + child.getMeasuredHeight(); int width = child.getMeasuredWidth(); childLeft = 0; childRight = childLeft + width; child.layout(childLeft, childTop, childRight, childBottom); }
private void measureScrapChild( RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { View view = recycler.getViewForPosition(position); if (view != null) { RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } }
private void layoutChildren() { int total = getTotalPages(); int x = mPaddingLeft; for (int i = 0; i < total; i++) { View child = getScreenAt(i); if (null == child) continue; LayoutParams lp = child.getLayoutParams(); // Get measure specs int childHeightSpec = ViewGroup.getChildMeasureSpec( mHeightMeasureSpec, mPaddingTop + mPaddingBottom, lp.height); int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, mPaddingLeft + mPaddingRight, lp.width); // Measure child child.measure(childWidthSpec, childHeightSpec); int childLeft; int childRight; // Position vertically based on gravity setting int childTop = calculateTop(child, true); int childBottom = childTop + child.getMeasuredHeight(); int width = child.getMeasuredWidth(); childLeft = x; childRight = childLeft + width; child.layout(childLeft, childTop, childRight, childBottom); x = childRight; } }
/** * Measure the provided child. * * @param child The child. */ private void measureChild(View child) { ViewGroup.LayoutParams childLayoutParams = getLayoutParams(child); int childHeightSpec = ViewGroup.getChildMeasureSpec( mHeightMeasureSpec, getPaddingTop() + getPaddingBottom(), childLayoutParams.height); int childWidthSpec; if (childLayoutParams.width > 0) { childWidthSpec = MeasureSpec.makeMeasureSpec(childLayoutParams.width, MeasureSpec.EXACTLY); } else { childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpec); }
/** * 手动测量布局大小 * * @param view 被测量的布局 * @param width 布局默认宽度 * @param height 布局默认高度 示例: measureView(view, ViewGroup.LayoutParams.MATCH_PARENT, * ViewGroup.LayoutParams.WRAP_CONTENT); */ public static void measureView(View view, int width, int height) { ViewGroup.LayoutParams params = view.getLayoutParams(); if (params == null) { params = new ViewGroup.LayoutParams(width, height); } int mWidth = ViewGroup.getChildMeasureSpec(0, 0, params.width); int mHeight; int tempHeight = params.height; if (tempHeight > 0) { mHeight = View.MeasureSpec.makeMeasureSpec(tempHeight, View.MeasureSpec.EXACTLY); } else { mHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); } view.measure(mWidth, mHeight); }
private void measureView(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(0, 0 + 0, 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); }
/** 执行测量,执行完成之后只需调用View的getMeasuredXXX()方法即可获取测量结果 */ public static final View measure(View view) { ViewGroup.LayoutParams p = view.getLayoutParams(); if (p == null) { p = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width); int lpHeight = p.height; int childHeightSpec; if (lpHeight > 0) { childHeightSpec = View.MeasureSpec.makeMeasureSpec(lpHeight, View.MeasureSpec.EXACTLY); } else { childHeightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); } view.measure(childWidthSpec, childHeightSpec); return view; }
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); } }