List of usage examples for android.view View measure
public final void measure(int widthMeasureSpec, int heightMeasureSpec)
This is called to find out how big a view should be.
From source file:com.example.mvpdemo.widget.NarrowParentViewPager.java
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { Log.i("xx", "================= onLayout ================="); final int count = getChildCount(); int width = r - l; int height = b - t; int paddingLeft = getPaddingLeft(); int paddingTop = getPaddingTop(); int paddingRight = getPaddingRight(); int paddingBottom = getPaddingBottom(); final int scrollX = getScrollX(); int decorCount = 0; // First pass - decor views. We need to do this in two passes so that // we have the proper offsets for non-decor views later. for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); int childLeft = 0; int childTop = 0; if (lp.isDecor) { final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK; final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; switch (hgrav) { default: childLeft = paddingLeft; break; case Gravity.LEFT: childLeft = paddingLeft; paddingLeft += child.getMeasuredWidth(); break; case Gravity.CENTER_HORIZONTAL: childLeft = Math.max((width - child.getMeasuredWidth()) / 2, paddingLeft); break; case Gravity.RIGHT: childLeft = width - paddingRight - child.getMeasuredWidth(); paddingRight += child.getMeasuredWidth(); break; }/*from w ww . jav a 2s . c o m*/ switch (vgrav) { default: childTop = paddingTop; break; case Gravity.TOP: childTop = paddingTop; paddingTop += child.getMeasuredHeight(); break; case Gravity.CENTER_VERTICAL: childTop = Math.max((height - child.getMeasuredHeight()) / 2, paddingTop); break; case Gravity.BOTTOM: childTop = height - paddingBottom - child.getMeasuredHeight(); paddingBottom += child.getMeasuredHeight(); break; } childLeft += scrollX; child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); decorCount++; } } } final int childWidth = width - paddingLeft - paddingRight - 2 * (OFFSET); // Page views. Do this once we have the right padding offsets from above. for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE && (child == mCurrent && mDragDistance == 0 || child != mCurrent)) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); ItemInfo ii; if (!lp.isDecor && (ii = infoForChild(child)) != null) { Log.i("Narrow", "INDEX = " + i + " offset = " + ii.offset); int loff = (int) (childWidth * ii.offset); int childLeft = paddingLeft + loff; int childTop = paddingTop; if (lp.needsMeasure) { // This was added during layout and needs measurement. // Do it now that we know what we're working with. lp.needsMeasure = false; final int widthSpec = MeasureSpec.makeMeasureSpec((int) (childWidth * lp.widthFactor), MeasureSpec.EXACTLY); final int heightSpec = MeasureSpec .makeMeasureSpec((int) (height - paddingTop - paddingBottom), MeasureSpec.EXACTLY); child.measure(widthSpec, heightSpec); } if (DEBUG) Log.v(TAG, "Positioning #" + i + " " + child + " f=" + ii.object + ":" + childLeft + "," + childTop + " " + child.getMeasuredWidth() + "x" + child.getMeasuredHeight()); child.layout(childLeft + OFFSET + PADDING, childTop + (int) ((OFFSET + PADDING) * (float) getHeight() / getWidth()), (int) (childLeft + child.getMeasuredWidth()) + OFFSET + PADDING, childTop + child.getMeasuredHeight()); } } } mTopPageBounds = paddingTop; mBottomPageBounds = height - paddingBottom; mDecorChildCount = decorCount; if (mFirstLayout) { scrollToItem(mCurItem, false, 0, false); } mFirstLayout = false; }
From source file:com.aliasapps.seq.scroller.TwoWayView.java
private void measureScrapChild(View scrapChild, int position, int secondaryMeasureSpec) { LayoutParams lp = (LayoutParams) scrapChild.getLayoutParams(); if (lp == null) { lp = generateDefaultLayoutParams(); scrapChild.setLayoutParams(lp);//ww w . jav a2 s . c om } lp.viewType = mAdapter.getItemViewType(position); lp.forceAdd = true; final int widthMeasureSpec; final int heightMeasureSpec; if (mIsVertical) { widthMeasureSpec = secondaryMeasureSpec; heightMeasureSpec = getChildHeightMeasureSpec(lp); } else { widthMeasureSpec = getChildWidthMeasureSpec(lp); heightMeasureSpec = secondaryMeasureSpec; } scrapChild.measure(widthMeasureSpec, heightMeasureSpec); }
From source file:android.improving.utils.views.cardsview.OrientedViewPager.java
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); int width = r - l; int height = b - t; int paddingLeft = getPaddingLeft(); int paddingTop = getPaddingTop(); int paddingRight = getPaddingRight(); int paddingBottom = getPaddingBottom(); final int scroll = (mOrientation == Orientation.VERTICAL) ? getScrollY() : getScrollX(); int decorCount = 0; // First pass - decor views. We need to do this in two passes so that // we have the proper offsets for non-decor views later. for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); int childLeft = 0; int childTop = 0; if (lp.isDecor) { final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK; final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; switch (hgrav) { default: childLeft = paddingLeft; break; case Gravity.LEFT: childLeft = paddingLeft; paddingLeft += child.getMeasuredWidth(); break; case Gravity.CENTER_HORIZONTAL: childLeft = Math.max((width - child.getMeasuredWidth()) / 2, paddingLeft); break; case Gravity.RIGHT: childLeft = width - paddingRight - child.getMeasuredWidth(); paddingRight += child.getMeasuredWidth(); break; }/*from ww w. ja v a2 s . c o m*/ switch (vgrav) { default: childTop = paddingTop; break; case Gravity.TOP: childTop = paddingTop; paddingTop += child.getMeasuredHeight(); break; case Gravity.CENTER_VERTICAL: childTop = Math.max((height - child.getMeasuredHeight()) / 2, paddingTop); break; case Gravity.BOTTOM: childTop = height - paddingBottom - child.getMeasuredHeight(); paddingBottom += child.getMeasuredHeight(); break; } if (mOrientation == Orientation.VERTICAL) { childTop += scroll; } else { childLeft += scroll; } child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); decorCount++; } } } final int childSize = (mOrientation == Orientation.VERTICAL) ? height - paddingTop - paddingBottom : width - paddingLeft - paddingRight; // Page views. Do this once we have the right padding offsets from above. for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); ItemInfo ii; if (!lp.isDecor && (ii = infoForChild(child)) != null) { int topLeftoff = (int) (childSize * ii.offset); int childLeft; int childTop; if (mOrientation == Orientation.VERTICAL) { childLeft = paddingLeft; childTop = paddingTop + topLeftoff; if (lp.needsMeasure) { // This was added during layout and needs measurement. // Do it now that we know what we're working with. lp.needsMeasure = false; final int widthSpec = MeasureSpec.makeMeasureSpec( (int) (width - paddingLeft - paddingRight), MeasureSpec.EXACTLY); final int heightSpec = MeasureSpec.makeMeasureSpec((int) (childSize * lp.heightFactor), MeasureSpec.EXACTLY); child.measure(widthSpec, heightSpec); } } else { childLeft = paddingLeft + topLeftoff; childTop = paddingTop; if (lp.needsMeasure) { // This was added during layout and needs measurement. // Do it now that we know what we're working with. lp.needsMeasure = false; final int widthSpec = MeasureSpec.makeMeasureSpec((int) (childSize * lp.widthFactor), MeasureSpec.EXACTLY); final int heightSpec = MeasureSpec.makeMeasureSpec( (int) (height - paddingTop - paddingBottom), MeasureSpec.EXACTLY); child.measure(widthSpec, heightSpec); } } if (DEBUG) Log.v(TAG, "Positioning #" + i + " " + child + " f=" + ii.object + ":" + childLeft + "," + childTop + " " + child.getMeasuredWidth() + "x" + child.getMeasuredHeight()); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } mTopLeftPageBounds = (mOrientation == Orientation.VERTICAL) ? paddingLeft : paddingTop; mBottomRightPageBounds = (mOrientation == Orientation.VERTICAL) ? width - paddingRight : height - paddingBottom; mDecorChildCount = decorCount; if (mFirstLayout) { scrollToItem(mCurItem, false, 0, false); } mFirstLayout = false; }
From source file:cn.androidy.materialdesignsample.ryanharterviewpager.ViewPager.java
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); int width = r - l; int height = b - t; int paddingLeft = getPaddingLeft(); int paddingTop = getPaddingTop(); int paddingRight = getPaddingRight(); int paddingBottom = getPaddingBottom(); final int scrollX = getScrollX(); final int scrollY = getScrollY(); int decorCount = 0; // First pass - decor views. We need to do this in two passes so that // we have the proper offsets for non-decor views later. for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); int childLeft = 0; int childTop = 0; if (lp.isDecor) { final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK; final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; switch (hgrav) { default: childLeft = paddingLeft; break; case Gravity.LEFT: childLeft = paddingLeft; paddingLeft += child.getMeasuredWidth(); break; case Gravity.CENTER_HORIZONTAL: childLeft = Math.max((width - child.getMeasuredWidth()) / 2, paddingLeft); break; case Gravity.RIGHT: childLeft = width - paddingRight - child.getMeasuredWidth(); paddingRight += child.getMeasuredWidth(); break; }/*from w w w . j a va2s . co m*/ switch (vgrav) { default: childTop = paddingTop; break; case Gravity.TOP: childTop = paddingTop; paddingTop += child.getMeasuredHeight(); break; case Gravity.CENTER_VERTICAL: childTop = Math.max((height - child.getMeasuredHeight()) / 2, paddingTop); break; case Gravity.BOTTOM: childTop = height - paddingBottom - child.getMeasuredHeight(); paddingBottom += child.getMeasuredHeight(); break; } if (isOrientationHorizontal()) { childLeft += scrollX; } else { childTop += scrollY; } child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); decorCount++; } } } int childSize = 0; if (isOrientationHorizontal()) { childSize = width - paddingLeft - paddingRight; } else { childSize = height - paddingTop - paddingBottom; } // Page views. Do this once we have the right padding offsets from above. for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); ItemInfo ii; if (!lp.isDecor && (ii = infoForChild(child)) != null) { int loff = (int) (childSize * ii.offset); int childLeft = paddingLeft + (isOrientationHorizontal() ? loff : 0); int childTop = paddingTop + (isOrientationHorizontal() ? 0 : loff); if (lp.needsMeasure) { // This was added during layout and needs measurement. // Do it now that we know what we're working with. lp.needsMeasure = false; int widthSpec = 0, heightSpec = 0; if (isOrientationHorizontal()) { widthSpec = MeasureSpec.makeMeasureSpec((int) (childSize * lp.sizeFactor), MeasureSpec.EXACTLY); heightSpec = MeasureSpec.makeMeasureSpec((int) (height - paddingTop - paddingBottom), MeasureSpec.EXACTLY); } else { widthSpec = MeasureSpec.makeMeasureSpec((int) (width - paddingLeft - paddingRight), MeasureSpec.EXACTLY); heightSpec = MeasureSpec.makeMeasureSpec((int) (childSize * lp.sizeFactor), MeasureSpec.EXACTLY); } child.measure(widthSpec, heightSpec); } if (DEBUG) Log.v(TAG, "Positioning #" + i + " " + child + " f=" + ii.object + ":" + childLeft + "," + childTop + " " + child.getMeasuredWidth() + "x" + child.getMeasuredHeight()); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } mLeftPageBounds = paddingLeft; mTopPageBounds = paddingTop; mRightPageBounds = width - paddingRight; mBottomPageBounds = height - paddingBottom; mDecorChildCount = decorCount; if (mFirstLayout) { scrollToItem(mCurItem, false, 0, false); } mFirstLayout = false; }
From source file:com.guide.ViewPager.java
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); int width = r - l; int height = b - t; int paddingLeft = getPaddingLeft(); int paddingTop = getPaddingTop(); int paddingRight = getPaddingRight(); int paddingBottom = getPaddingBottom(); final int scrollX = getScrollX(); final int scrollY = getScrollY(); int decorCount = 0; // First pass - decor views. We need to do this in two passes so that // we have the proper offsets for non-decor views later. for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); int childLeft = 0; int childTop = 0; if (lp.isDecor) { final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK; final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; switch (hgrav) { default: childLeft = paddingLeft; break; case Gravity.LEFT: childLeft = paddingLeft; paddingLeft += child.getMeasuredWidth(); break; case Gravity.CENTER_HORIZONTAL: childLeft = Math.max((width - child.getMeasuredWidth()) / 2, paddingLeft); break; case Gravity.RIGHT: childLeft = width - paddingRight - child.getMeasuredWidth(); paddingRight += child.getMeasuredWidth(); break; }/*from w w w .j a v a 2 s.com*/ switch (vgrav) { default: childTop = paddingTop; break; case Gravity.TOP: childTop = paddingTop; paddingTop += child.getMeasuredHeight(); break; case Gravity.CENTER_VERTICAL: childTop = Math.max((height - child.getMeasuredHeight()) / 2, paddingTop); break; case Gravity.BOTTOM: childTop = height - paddingBottom - child.getMeasuredHeight(); paddingBottom += child.getMeasuredHeight(); break; } if (isOrientationHorizontal()) { childLeft += scrollX; } else { childTop += scrollY; } child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); decorCount++; } } } int childSize = 0; if (isOrientationHorizontal()) { childSize = width - paddingLeft - paddingRight; } else { childSize = height - paddingTop - paddingBottom; } // Page views. Do this once we have the right padding offsets from // above. for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); ItemInfo ii; if (!lp.isDecor && (ii = infoForChild(child)) != null) { int loff = (int) (childSize * ii.offset); int childLeft = paddingLeft + (isOrientationHorizontal() ? loff : 0); int childTop = paddingTop + (isOrientationHorizontal() ? 0 : loff); if (lp.needsMeasure) { // This was added during layout and needs measurement. // Do it now that we know what we're working with. lp.needsMeasure = false; int widthSpec = 0, heightSpec = 0; if (isOrientationHorizontal()) { widthSpec = MeasureSpec.makeMeasureSpec((int) (childSize * lp.sizeFactor), MeasureSpec.EXACTLY); heightSpec = MeasureSpec.makeMeasureSpec((int) (height - paddingTop - paddingBottom), MeasureSpec.EXACTLY); } else { widthSpec = MeasureSpec.makeMeasureSpec((int) (width - paddingLeft - paddingRight), MeasureSpec.EXACTLY); heightSpec = MeasureSpec.makeMeasureSpec((int) (childSize * lp.sizeFactor), MeasureSpec.EXACTLY); } child.measure(widthSpec, heightSpec); } if (DEBUG) Log.v(TAG, "Positioning #" + i + " " + child + " f=" + ii.object + ":" + childLeft + "," + childTop + " " + child.getMeasuredWidth() + "x" + child.getMeasuredHeight()); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } mLeftPageBounds = paddingLeft; mTopPageBounds = paddingTop; mRightPageBounds = width - paddingRight; mBottomPageBounds = height - paddingBottom; mDecorChildCount = decorCount; if (mFirstLayout) { scrollToItem(mCurItem, false, 0, false); } mFirstLayout = false; }
From source file:com.actionbarsherlock.internal.view.menu.ActionMenuView.java
private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) { // We already know the width mode is EXACTLY if we're here. final int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); final int widthPadding = getPaddingLeft() + getPaddingRight(); final int heightPadding = getPaddingTop() + getPaddingBottom(); widthSize -= widthPadding;//from ww w.jav a 2s . co m // Divide the view into cells. final int cellCount = widthSize / mMinCellSize; final int cellSizeRemaining = widthSize % mMinCellSize; if (cellCount == 0) { // Give up, nothing fits. setMeasuredDimension(widthSize, 0); return; } final int cellSize = mMinCellSize + cellSizeRemaining / cellCount; int cellsRemaining = cellCount; int maxChildHeight = 0; int maxCellsUsed = 0; int expandableItemCount = 0; int visibleItemCount = 0; boolean hasOverflow = false; // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64. long smallestItemsAt = 0; final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); if (child.getVisibility() == GONE) continue; final boolean isGeneratedItem = child instanceof ActionMenuItemView; visibleItemCount++; if (isGeneratedItem) { // Reset padding for generated menu item views; it may change below // and views are recycled. child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0); } final LayoutParams lp = (LayoutParams) child.getLayoutParams(); lp.expanded = false; lp.extraPixels = 0; lp.cellsUsed = 0; lp.expandable = false; lp.leftMargin = 0; lp.rightMargin = 0; lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText(); // Overflow always gets 1 cell. No more, no less. final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining; final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable, heightMeasureSpec, heightPadding); maxCellsUsed = Math.max(maxCellsUsed, cellsUsed); if (lp.expandable) expandableItemCount++; if (lp.isOverflowButton) hasOverflow = true; cellsRemaining -= cellsUsed; maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight()); if (cellsUsed == 1) smallestItemsAt |= (1 << i); } // When we have overflow and a single expanded (text) item, we want to try centering it // visually in the available space even though overflow consumes some of it. final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2; // Divide space for remaining cells if we have items that can expand. // Try distributing whole leftover cells to smaller items first. boolean needsExpansion = false; while (expandableItemCount > 0 && cellsRemaining > 0) { int minCells = Integer.MAX_VALUE; long minCellsAt = 0; // Bit locations are indices of relevant child views int minCellsItemCount = 0; for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); // Don't try to expand items that shouldn't. if (!lp.expandable) continue; // Mark indices of children that can receive an extra cell. if (lp.cellsUsed < minCells) { minCells = lp.cellsUsed; minCellsAt = 1 << i; minCellsItemCount = 1; } else if (lp.cellsUsed == minCells) { minCellsAt |= 1 << i; minCellsItemCount++; } } // Items that get expanded will always be in the set of smallest items when we're done. smallestItemsAt |= minCellsAt; if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop. // We have enough cells, all minimum size items will be incremented. minCells++; for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if ((minCellsAt & (1 << i)) == 0) { // If this item is already at our small item count, mark it for later. if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i; continue; } if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) { // Add padding to this item such that it centers. child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0); } lp.cellsUsed++; lp.expanded = true; cellsRemaining--; } needsExpansion = true; } // Divide any space left that wouldn't divide along cell boundaries // evenly among the smallest items final boolean singleItem = !hasOverflow && visibleItemCount == 1; if (cellsRemaining > 0 && smallestItemsAt != 0 && (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) { float expandCount = Long.bitCount(smallestItemsAt); if (!singleItem) { // The items at the far edges may only expand by half in order to pin to either side. if ((smallestItemsAt & 1) != 0) { LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams(); if (!lp.preventEdgeOffset) expandCount -= 0.5f; } if ((smallestItemsAt & (1 << (childCount - 1))) != 0) { LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams()); if (!lp.preventEdgeOffset) expandCount -= 0.5f; } } final int extraPixels = expandCount > 0 ? (int) (cellsRemaining * cellSize / expandCount) : 0; for (int i = 0; i < childCount; i++) { if ((smallestItemsAt & (1 << i)) == 0) continue; final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (child instanceof ActionMenuItemView) { // If this is one of our views, expand and measure at the larger size. lp.extraPixels = extraPixels; lp.expanded = true; if (i == 0 && !lp.preventEdgeOffset) { // First item gets part of its new padding pushed out of sight. // The last item will get this implicitly from layout. lp.leftMargin = -extraPixels / 2; } needsExpansion = true; } else if (lp.isOverflowButton) { lp.extraPixels = extraPixels; lp.expanded = true; lp.rightMargin = -extraPixels / 2; needsExpansion = true; } else { // If we don't know what it is, give it some margins instead // and let it center within its space. We still want to pin // against the edges. if (i != 0) { lp.leftMargin = extraPixels / 2; } if (i != childCount - 1) { lp.rightMargin = extraPixels / 2; } } } cellsRemaining = 0; } // Remeasure any items that have had extra space allocated to them. if (needsExpansion) { int heightSpec = MeasureSpec.makeMeasureSpec(heightSize - heightPadding, heightMode); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (!lp.expanded) continue; final int width = lp.cellsUsed * cellSize + lp.extraPixels; child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec); } } if (heightMode != MeasureSpec.EXACTLY) { heightSize = maxChildHeight; } setMeasuredDimension(widthSize, heightSize); //UNUSED mMeasuredExtraWidth = cellsRemaining * cellSize; }
From source file:app.umitems.greenclock.widget.sgv.StaggeredGridView.java
/** * Measure and layout all currently visible children. * * @param queryAdapter true to requery the adapter for view data *///from w w w .ja va 2 s. com final void layoutChildren(boolean queryAdapter) { final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int itemMargin = mItemMargin; final int availableWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)); final int colWidth = availableWidth / mColCount; // The availableWidth may not be divisible by mColCount. Keep the // remainder. It will be added to the width of the last view in the row. final int remainder = availableWidth % mColCount; boolean viewsRemovedInLayout = false; // If we're animating out stale views, then we want to defer recycling of views. final boolean deferRecyclingForAnimation = mAnimationOutMode != AnimationOut.NONE; if (!deferRecyclingForAnimation) { final int childCount = getChildCount(); // If the latest data set has fewer data items than mFirstPosition, don't keep any // views on screen, and just let the layout logic below retrieve appropriate views // from the recycler. final int viewsToKeepOnScreen = (mItemCount <= mFirstPosition) ? 0 : mItemCount - mFirstPosition; if (childCount > viewsToKeepOnScreen) { // If there are more views laid out than the number of data items remaining to be // laid out, recycle the extraneous views. recycleViewsInRange(viewsToKeepOnScreen, childCount - 1); viewsRemovedInLayout = true; } } else { mViewsToAnimateOut.clear(); } for (int i = 0; i < getChildCount(); i++) { final int position = mFirstPosition + i; View child = getChildAt(i); final int highestAvailableLayoutPosition = mItemBottoms[getNextColumnDown()]; if (deferRecyclingForAnimation && (position >= mItemCount || highestAvailableLayoutPosition >= getHeight())) { // For the remainder of views on screen, they should not be on screen, so we can // skip layout. Add them to the list of views to animate out. // We should only get in this position if deferRecyclingForAnimation = true, // otherwise, we should've recycled all views before getting into this layout loop. mViewsToAnimateOut.add(child); continue; } LayoutParams lp = null; int col = -1; if (child != null) { lp = (LayoutParams) child.getLayoutParams(); col = lp.column; } final boolean needsLayout = queryAdapter || child == null || child.isLayoutRequested(); if (queryAdapter) { View newView = null; if (deferRecyclingForAnimation) { // If we are deferring recycling for animation, then we don't want to pass the // current child in to obtainView for re-use. obtainView() in this case should // try to find the view belonging to this item on screen, or populate a fresh // one from the recycler. newView = obtainView(position); } else { newView = obtainView(position, child); } // Update layout params since they may have changed lp = (LayoutParams) newView.getLayoutParams(); if (newView != child) { if (child != null && !deferRecyclingForAnimation) { mRecycler.addScrap(child); removeViewInLayout(child); viewsRemovedInLayout = true; } // If this view is already in the layout hierarchy, we can just detach it // from the parent and re-attach it at the correct index. If the view has // already been removed from the layout hierarchy, getParent() == null. if (newView.getParent() == this) { detachViewFromParent(newView); attachViewToParent(newView, i, lp); } else { addViewInLayout(newView, i, lp); } } child = newView; // Since the data has changed, we need to make sure the next child is in the // right column. We choose the next column down (vs. next column up) because we // are filling from the top of the screen downwards as we iterate through // visible children. (We take span into account below.) lp.column = getNextColumnDown(); col = lp.column; } setReorderingArea(lp); final int span = Math.min(mColCount, lp.span); // Given the span, check if there's enough space to put this view at this column. // IMPORTANT Propagate the same logic to {@link #calculateLayoutStartOffsets}. if (span > 1) { if (mIsRtlLayout) { // For RTL layout, if the current column index is less than the span of the // child, then we know that there is not enough room remaining to lay this // child out (e.g., if col == 0, but span == 2, then laying this child down // at column = col would put us out of bound into a negative column index.). // For this scenario, reset the index back to the right-most column, and lay // out the child at this position where we can ensure that we can display as // much of the child as possible. if (col + 1 < span) { col = mColCount - 1; } } else { if (mColCount - col < span) { // If not, reset the col to 0. col = 0; } } lp.column = col; } int widthSize = (colWidth * span + itemMargin * (span - 1)); // If it is rtl, we layout the view from col to col - span + // 1. If it reaches the most left column, i.e. we added the // additional width. So the check it span == col +1 if ((mIsRtlLayout && span == col + 1) || (!mIsRtlLayout && span + col == mColCount)) { widthSize += remainder; } if (needsLayout) { final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); final int heightSpec; if (lp.height == LayoutParams.WRAP_CONTENT) { heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } else { heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); } child.measure(widthSpec, heightSpec); } // Place the top of this child beneath the last by finding the lowest coordinate across // the columns that this child will span. For LTR layout, we scan across from left to // right, and for RTL layout, we scan from right to left. // TODO: Consolidate this logic with getNextRecordDown() in the future, as that method // already calculates the margins for us. This will keep the implementation consistent // with fillUp() and fillDown(). int childTop = mItemBottoms[col] + mItemMargin; if (span > 1) { int lowest = childTop; for (int spanIndex = 0; spanIndex < span; spanIndex++) { final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex; final int bottom = mItemBottoms[index] + mItemMargin; if (bottom > lowest) { lowest = bottom; } } childTop = lowest; } final int childHeight = child.getMeasuredHeight(); final int childBottom = childTop + childHeight; int childLeft = 0; int childRight = 0; if (mIsRtlLayout) { childRight = (getWidth() - paddingRight) - (mColCount - col - 1) * (colWidth + itemMargin); childLeft = childRight - child.getMeasuredWidth(); } else { childLeft = paddingLeft + col * (colWidth + itemMargin); childRight = childLeft + child.getMeasuredWidth(); } /* Log.v(TAG, "[layoutChildren] height: " + childHeight + " top: " + childTop + " bottom: " + childBottom + " left: " + childLeft + " column: " + col + " position: " + position + " id: " + lp.id); */ child.layout(childLeft, childTop, childRight, childBottom); if (lp.id == mFocusedChildIdToScrollIntoView) { child.requestFocus(); } for (int spanIndex = 0; spanIndex < span; spanIndex++) { final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex; mItemBottoms[index] = childBottom; } // Whether or not LayoutRecords may have already existed for the view at this position // on screen, we'll update it after we lay out to ensure that the LayoutRecord // has the most updated information about the view at this position. We can be assured // that all views before those on screen (views with adapter position < mFirstPosition) // have the correct LayoutRecords because calculateLayoutStartOffsets() would have // set them appropriately. LayoutRecord rec = mLayoutRecords.get(position); if (rec == null) { rec = new LayoutRecord(); mLayoutRecords.put(position, rec); } rec.column = lp.column; rec.height = childHeight; rec.id = lp.id; rec.span = span; } // It appears that removeViewInLayout() does not invalidate. So if we make use of this // method during layout, we should invalidate explicitly. if (viewsRemovedInLayout || deferRecyclingForAnimation) { invalidate(); } }
From source file:com.deepak.myclock.widget.sgv.StaggeredGridView.java
/** * Measure and layout all currently visible children. * * @param queryAdapter true to requery the adapter for view data *///from w w w . ja v a 2 s .c o m final void layoutChildren(boolean queryAdapter) { final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int itemMargin = mItemMargin; final int availableWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)); final int colWidth = availableWidth / mColCount; // The availableWidth may not be divisible by mColCount. Keep the // remainder. It will be added to the width of the last view in the row. final int remainder = availableWidth % mColCount; boolean viewsRemovedInLayout = false; // If we're animating out stale views, then we want to defer recycling of views. final boolean deferRecyclingForAnimation = mAnimationOutMode != SgvAnimationHelper.AnimationOut.NONE; if (!deferRecyclingForAnimation) { final int childCount = getChildCount(); // If the latest data set has fewer data items than mFirstPosition, don't keep any // views on screen, and just let the layout logic below retrieve appropriate views // from the recycler. final int viewsToKeepOnScreen = (mItemCount <= mFirstPosition) ? 0 : mItemCount - mFirstPosition; if (childCount > viewsToKeepOnScreen) { // If there are more views laid out than the number of data items remaining to be // laid out, recycle the extraneous views. recycleViewsInRange(viewsToKeepOnScreen, childCount - 1); viewsRemovedInLayout = true; } } else { mViewsToAnimateOut.clear(); } for (int i = 0; i < getChildCount(); i++) { final int position = mFirstPosition + i; View child = getChildAt(i); final int highestAvailableLayoutPosition = mItemBottoms[getNextColumnDown()]; if (deferRecyclingForAnimation && (position >= mItemCount || highestAvailableLayoutPosition >= getHeight())) { // For the remainder of views on screen, they should not be on screen, so we can // skip layout. Add them to the list of views to animate out. // We should only get in this position if deferRecyclingForAnimation = true, // otherwise, we should've recycled all views before getting into this layout loop. mViewsToAnimateOut.add(child); continue; } LayoutParams lp = null; int col = -1; if (child != null) { lp = (LayoutParams) child.getLayoutParams(); col = lp.column; } final boolean needsLayout = queryAdapter || child == null || child.isLayoutRequested(); if (queryAdapter) { View newView = null; if (deferRecyclingForAnimation) { // If we are deferring recycling for animation, then we don't want to pass the // current child in to obtainView for re-use. obtainView() in this case should // try to find the view belonging to this item on screen, or populate a fresh // one from the recycler. newView = obtainView(position); } else { newView = obtainView(position, child); } // Update layout params since they may have changed lp = (LayoutParams) newView.getLayoutParams(); if (newView != child) { if (child != null && !deferRecyclingForAnimation) { mRecycler.addScrap(child); removeViewInLayout(child); viewsRemovedInLayout = true; } // If this view is already in the layout hierarchy, we can just detach it // from the parent and re-attach it at the correct index. If the view has // already been removed from the layout hierarchy, getParent() == null. if (newView.getParent() == this) { detachViewFromParent(newView); attachViewToParent(newView, i, lp); } else { addViewInLayout(newView, i, lp); } } child = newView; // Since the data has changed, we need to make sure the next child is in the // right column. We choose the next column down (vs. next column up) because we // are filling from the top of the screen downwards as we iterate through // visible children. (We take span into account below.) lp.column = getNextColumnDown(); col = lp.column; } setReorderingArea(lp); final int span = Math.min(mColCount, lp.span); // Given the span, check if there's enough space to put this view at this column. // IMPORTANT Propagate the same logic to {@link #calculateLayoutStartOffsets}. if (span > 1) { if (mIsRtlLayout) { // For RTL layout, if the current column index is less than the span of the // child, then we know that there is not enough room remaining to lay this // child out (e.g., if col == 0, but span == 2, then laying this child down // at column = col would put us out of bound into a negative column index.). // For this scenario, reset the index back to the right-most column, and lay // out the child at this position where we can ensure that we can display as // much of the child as possible. if (col + 1 < span) { col = mColCount - 1; } } else { if (mColCount - col < span) { // If not, reset the col to 0. col = 0; } } lp.column = col; } int widthSize = (colWidth * span + itemMargin * (span - 1)); // If it is rtl, we layout the view from col to col - span + // 1. If it reaches the most left column, i.e. we added the // additional width. So the check it span == col +1 if ((mIsRtlLayout && span == col + 1) || (!mIsRtlLayout && span + col == mColCount)) { widthSize += remainder; } if (needsLayout) { final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); final int heightSpec; if (lp.height == LayoutParams.WRAP_CONTENT) { heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } else { heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); } child.measure(widthSpec, heightSpec); } // Place the top of this child beneath the last by finding the lowest coordinate across // the columns that this child will span. For LTR layout, we scan across from left to // right, and for RTL layout, we scan from right to left. // TODO: Consolidate this logic with getNextRecordDown() in the future, as that method // already calculates the margins for us. This will keep the implementation consistent // with fillUp() and fillDown(). int childTop = mItemBottoms[col] + mItemMargin; if (span > 1) { int lowest = childTop; for (int spanIndex = 0; spanIndex < span; spanIndex++) { final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex; final int bottom = mItemBottoms[index] + mItemMargin; if (bottom > lowest) { lowest = bottom; } } childTop = lowest; } final int childHeight = child.getMeasuredHeight(); final int childBottom = childTop + childHeight; int childLeft = 0; int childRight = 0; if (mIsRtlLayout) { childRight = (getWidth() - paddingRight) - (mColCount - col - 1) * (colWidth + itemMargin); childLeft = childRight - child.getMeasuredWidth(); } else { childLeft = paddingLeft + col * (colWidth + itemMargin); childRight = childLeft + child.getMeasuredWidth(); } /* Log.v(TAG, "[layoutChildren] height: " + childHeight + " top: " + childTop + " bottom: " + childBottom + " left: " + childLeft + " column: " + col + " position: " + position + " id: " + lp.id); */ child.layout(childLeft, childTop, childRight, childBottom); if (lp.id == mFocusedChildIdToScrollIntoView) { child.requestFocus(); } for (int spanIndex = 0; spanIndex < span; spanIndex++) { final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex; mItemBottoms[index] = childBottom; } // Whether or not LayoutRecords may have already existed for the view at this position // on screen, we'll update it after we lay out to ensure that the LayoutRecord // has the most updated information about the view at this position. We can be assured // that all views before those on screen (views with adapter position < mFirstPosition) // have the correct LayoutRecords because calculateLayoutStartOffsets() would have // set them appropriately. LayoutRecord rec = mLayoutRecords.get(position); if (rec == null) { rec = new LayoutRecord(); mLayoutRecords.put(position, rec); } rec.column = lp.column; rec.height = childHeight; rec.id = lp.id; rec.span = span; } // It appears that removeViewInLayout() does not invalidate. So if we make use of this // method during layout, we should invalidate explicitly. if (viewsRemovedInLayout || deferRecyclingForAnimation) { invalidate(); } }
From source file:android.support.v7.widget.LinearLayoutCompat.java
/** * Measures the children when the orientation of this LinearLayout is set * to {@link #VERTICAL}.//from ww w. j av a 2s .c o m * * @param widthMeasureSpec Horizontal space requirements as imposed by the parent. * @param heightMeasureSpec Vertical space requirements as imposed by the parent. * * @see #getOrientation() * @see #setOrientation(int) * @see #onMeasure(int, int) */ void measureVertical(int widthMeasureSpec, int heightMeasureSpec) { mTotalLength = 0; int maxWidth = 0; int childState = 0; int alternativeMaxWidth = 0; int weightedMaxWidth = 0; boolean allFillParent = true; float totalWeight = 0; final int count = getVirtualChildCount(); final int widthMode = MeasureSpec.getMode(widthMeasureSpec); final int heightMode = MeasureSpec.getMode(heightMeasureSpec); boolean matchWidth = false; boolean skippedMeasure = false; final int baselineChildIndex = mBaselineAlignedChildIndex; final boolean useLargestChild = mUseLargestChild; int largestChildHeight = Integer.MIN_VALUE; // See how tall everyone is. Also remember max width. for (int i = 0; i < count; ++i) { final View child = getVirtualChildAt(i); if (child == null) { mTotalLength += measureNullChild(i); continue; } if (child.getVisibility() == View.GONE) { i += getChildrenSkipCount(child, i); continue; } if (hasDividerBeforeChildAt(i)) { mTotalLength += mDividerHeight; } LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); totalWeight += lp.weight; if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) { // Optimization: don't bother measuring children who are going to use // leftover space. These views will get measured again down below if // there is any leftover space. final int totalLength = mTotalLength; mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin); skippedMeasure = true; } else { int oldHeight = Integer.MIN_VALUE; if (lp.height == 0 && lp.weight > 0) { // heightMode is either UNSPECIFIED or AT_MOST, and this // child wanted to stretch to fill available space. // Translate that to WRAP_CONTENT so that it does not end up // with a height of 0 oldHeight = 0; lp.height = LayoutParams.WRAP_CONTENT; } // Determine how big this child would like to be. If this or // previous children have given a weight, then we allow it to // use all available space (and we will shrink things later // if needed). measureChildBeforeLayout(child, i, widthMeasureSpec, 0, heightMeasureSpec, totalWeight == 0 ? mTotalLength : 0); if (oldHeight != Integer.MIN_VALUE) { lp.height = oldHeight; } final int childHeight = child.getMeasuredHeight(); final int totalLength = mTotalLength; mTotalLength = Math.max(totalLength, totalLength + childHeight + lp.topMargin + lp.bottomMargin + getNextLocationOffset(child)); if (useLargestChild) { largestChildHeight = Math.max(childHeight, largestChildHeight); } } /** * If applicable, compute the additional offset to the child's baseline * we'll need later when asked {@link #getBaseline}. */ if ((baselineChildIndex >= 0) && (baselineChildIndex == i + 1)) { mBaselineChildTop = mTotalLength; } // if we are trying to use a child index for our baseline, the above // book keeping only works if there are no children above it with // weight. fail fast to aid the developer. if (i < baselineChildIndex && lp.weight > 0) { 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."); } boolean matchWidthLocally = false; if (widthMode != MeasureSpec.EXACTLY && lp.width == LayoutParams.MATCH_PARENT) { // The width of the linear layout will scale, and at least one // child said it wanted to match our width. Set a flag // indicating that we need to remeasure at least that view when // we know our width. matchWidth = true; matchWidthLocally = true; } final int margin = lp.leftMargin + lp.rightMargin; final int measuredWidth = child.getMeasuredWidth() + margin; maxWidth = Math.max(maxWidth, measuredWidth); childState = ViewUtils.combineMeasuredStates(childState, ViewCompat.getMeasuredState(child)); allFillParent = allFillParent && lp.width == LayoutParams.MATCH_PARENT; if (lp.weight > 0) { /* * Widths of weighted Views are bogus if we end up * remeasuring, so keep them separate. */ weightedMaxWidth = Math.max(weightedMaxWidth, matchWidthLocally ? margin : measuredWidth); } else { alternativeMaxWidth = Math.max(alternativeMaxWidth, matchWidthLocally ? margin : measuredWidth); } i += getChildrenSkipCount(child, i); } if (mTotalLength > 0 && hasDividerBeforeChildAt(count)) { mTotalLength += mDividerHeight; } if (useLargestChild && (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED)) { mTotalLength = 0; for (int i = 0; i < count; ++i) { final View child = getVirtualChildAt(i); if (child == null) { mTotalLength += measureNullChild(i); continue; } if (child.getVisibility() == GONE) { i += getChildrenSkipCount(child, i); continue; } final LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) child .getLayoutParams(); // Account for negative margins final int totalLength = mTotalLength; mTotalLength = Math.max(totalLength, totalLength + largestChildHeight + lp.topMargin + lp.bottomMargin + getNextLocationOffset(child)); } } // Add in our padding mTotalLength += getPaddingTop() + getPaddingBottom(); int heightSize = mTotalLength; // Check against our minimum height heightSize = Math.max(heightSize, getSuggestedMinimumHeight()); // Reconcile our calculated size with the heightMeasureSpec int heightSizeAndState = ViewCompat.resolveSizeAndState(heightSize, heightMeasureSpec, 0); heightSize = heightSizeAndState & ViewCompat.MEASURED_SIZE_MASK; // Either expand children with weight to take up available space or // shrink them if they extend beyond our current bounds. If we skipped // measurement on any children, we need to measure them now. int delta = heightSize - mTotalLength; if (skippedMeasure || delta != 0 && totalWeight > 0.0f) { float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight; mTotalLength = 0; for (int i = 0; i < count; ++i) { final View child = getVirtualChildAt(i); if (child.getVisibility() == View.GONE) { continue; } LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); float childExtra = lp.weight; if (childExtra > 0) { // Child said it could absorb extra space -- give him his share int share = (int) (childExtra * delta / weightSum); weightSum -= childExtra; delta -= share; final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin, lp.width); // TODO: Use a field like lp.isMeasured to figure out if this // child has been previously measured if ((lp.height != 0) || (heightMode != MeasureSpec.EXACTLY)) { // child was measured once already above... // base new measurement on stored values int childHeight = child.getMeasuredHeight() + share; if (childHeight < 0) { childHeight = 0; } child.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY)); } else { // child was skipped in the loop above. // Measure for this first time here child.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(share > 0 ? share : 0, MeasureSpec.EXACTLY)); } // Child may now not fit in vertical dimension. childState = ViewUtils.combineMeasuredStates(childState, ViewCompat.getMeasuredState(child) & (ViewCompat.MEASURED_STATE_MASK >> ViewCompat.MEASURED_HEIGHT_STATE_SHIFT)); } final int margin = lp.leftMargin + lp.rightMargin; final int measuredWidth = child.getMeasuredWidth() + margin; maxWidth = Math.max(maxWidth, measuredWidth); boolean matchWidthLocally = widthMode != MeasureSpec.EXACTLY && lp.width == LayoutParams.MATCH_PARENT; alternativeMaxWidth = Math.max(alternativeMaxWidth, matchWidthLocally ? margin : measuredWidth); allFillParent = allFillParent && lp.width == LayoutParams.MATCH_PARENT; final int totalLength = mTotalLength; mTotalLength = Math.max(totalLength, totalLength + child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin + getNextLocationOffset(child)); } // Add in our padding mTotalLength += getPaddingTop() + getPaddingBottom(); // TODO: Should we recompute the heightSpec based on the new total length? } else { alternativeMaxWidth = Math.max(alternativeMaxWidth, weightedMaxWidth); // We have no limit, so make all weighted views as tall as the largest child. // Children will have already been measured once. if (useLargestChild && heightMode != MeasureSpec.EXACTLY) { for (int i = 0; i < count; i++) { final View child = getVirtualChildAt(i); if (child == null || child.getVisibility() == View.GONE) { continue; } final LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) child .getLayoutParams(); float childExtra = lp.weight; if (childExtra > 0) { child.measure(MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(largestChildHeight, MeasureSpec.EXACTLY)); } } } } if (!allFillParent && widthMode != MeasureSpec.EXACTLY) { maxWidth = alternativeMaxWidth; } maxWidth += getPaddingLeft() + getPaddingRight(); // Check against our minimum width maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); setMeasuredDimension(ViewCompat.resolveSizeAndState(maxWidth, widthMeasureSpec, childState), heightSizeAndState); if (matchWidth) { forceUniformWidth(count, heightMeasureSpec); } }