List of usage examples for android.view View getMeasuredWidth
public final int getMeasuredWidth()
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 w ww. ja va 2 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:com.android.leanlauncher.LauncherTransitionable.java
boolean startActivity(View v, Intent intent, Object tag) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try {/*from w w w. ja v a2 s. co m*/ // Only launch using the new animation if the shortcut has not opted out (this is a // private contract between launcher and may be ignored in the future). boolean useLaunchAnimation = (v != null) && !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION); LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this); UserManagerCompat userManager = UserManagerCompat.getInstance(this); UserHandleCompat user = null; if (intent.hasExtra(AppInfo.EXTRA_PROFILE)) { long serialNumber = intent.getLongExtra(AppInfo.EXTRA_PROFILE, -1); user = userManager.getUserForSerialNumber(serialNumber); } Bundle optsBundle = null; if (useLaunchAnimation) { ActivityOptions opts = Utilities.isLmpOrAbove() ? ActivityOptions.makeCustomAnimation(this, R.anim.task_open_enter, R.anim.no_anim) : ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); optsBundle = opts.toBundle(); } if (user == null || user.equals(UserHandleCompat.myUserHandle())) { // Could be launching some bookkeeping activity startActivity(intent, optsBundle); } else { // TODO Component can be null when shortcuts are supported for secondary user launcherApps.startActivityForProfile(intent.getComponent(), user, intent.getSourceBounds(), optsBundle); } return true; } catch (SecurityException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Launcher does not have the permission to launch " + intent + ". Make sure to create a MAIN intent-filter for the corresponding activity " + "or use the exported attribute for this activity. " + "tag=" + tag + " intent=" + intent, e); } return false; }
From source file:com.android.launcher2.Launcher.java
boolean startActivity(View v, Intent intent, Object tag) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try {/*from w w w . ja v a 2 s . c o m*/ // Only launch using the new animation if the shortcut has not opted out (this is a // private contract between launcher and may be ignored in the future). boolean useLaunchAnimation = (v != null) && !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION); if (useLaunchAnimation) { ActivityOptionsCompat opts = ActivityOptionsCompat.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); ActivityCompat.startActivity(this, intent, opts.toBundle()); } else { startActivity(intent); } return true; } catch (SecurityException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Launcher does not have the permission to launch " + intent + ". Make sure to create a MAIN intent-filter for the corresponding activity " + "or use the exported attribute for this activity. " + "tag=" + tag + " intent=" + intent, e); } return false; }
From source file:com.awrtechnologies.carbudgetsales.hlistview.widget.HListView.java
final int[] measureWithLargeChildren(int heightMeasureSpec, int startPosition, int endPosition, final int maxWidth, final int maxHeight, int disallowPartialChildPosition) { if (LOG_ENABLED) { Log.i(LOG_TAG, "measureWithLargeChildren, from " + startPosition + " to " + endPosition); }/*from w w w . jav a 2s . com*/ final ListAdapter adapter = mAdapter; if (adapter == null) { return new int[] { mListPadding.left + mListPadding.right, mListPadding.top + mListPadding.bottom }; } // Include the padding of the list int returnedWidth = mListPadding.left + mListPadding.right; int returnedHeight = mListPadding.top + mListPadding.bottom; final int dividerWidth = ((mDividerWidth > 0) && mDivider != null) ? mDividerWidth : 0; int childWidth = 0; int childHeight = 0; int i; View child; // mItemCount - 1 since endPosition parameter is inclusive endPosition = (endPosition == NO_POSITION) ? adapter.getCount() - 1 : endPosition; final AbsHListView.RecycleBin recycleBin = mRecycler; final boolean recyle = recycleOnMeasure(); final boolean[] isScrap = mIsScrap; for (i = startPosition; i <= endPosition; ++i) { child = obtainView(i, isScrap); measureScrapChildWidth(child, i, heightMeasureSpec); // Recycle the view before we possibly return from the method if (recyle && recycleBin.shouldRecycleViewType(((LayoutParams) child.getLayoutParams()).viewType)) { recycleBin.addScrapView(child, -1); } childWidth = Math.max(childWidth, child.getMeasuredWidth() + dividerWidth); childHeight = Math.max(childHeight, child.getMeasuredHeight()); } returnedWidth += childWidth; returnedHeight += childHeight; return new int[] { Math.min(returnedWidth, maxWidth), Math.min(returnedHeight, maxHeight) }; }
From source file:cn.ieclipse.af.view.StaggeredGridView.java
/** * Should be called with mPopulating set to true * * @param fromPosition Position to start filling from * @param overhang the number of extra pixels to fill beyond the current top edge * @return the max overhang beyond the beginning of the view of any added items at the top *//*from www . j a v a 2 s. co m*/ final int fillUp(int fromPosition, int overhang) { final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int itemMargin = mItemMargin; final int colWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount; final int gridTop = getPaddingTop(); final int fillTo = gridTop - overhang; int nextCol = getNextColumnUp(); int position = fromPosition; while (nextCol >= 0 && mItemTops[nextCol] > fillTo && position >= 0) { final View child = obtainView(position, null); LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (child.getParent() != this) { if (mInLayout) { addViewInLayout(child, 0, lp); } else { addView(child, 0); } } final int span = Math.min(mColCount, lp.span); final int widthSize = colWidth * span + itemMargin * (span - 1); final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); LayoutRecord rec; if (span > 1) { rec = getNextRecordUp(position, span); nextCol = rec.column; } else { rec = mLayoutRecords.get(position); } boolean invalidateBefore = false; if (rec == null) { rec = new LayoutRecord(); mLayoutRecords.put(position, rec); rec.column = nextCol; rec.span = span; } else if (span != rec.span) { rec.span = span; rec.column = nextCol; invalidateBefore = true; } else { nextCol = rec.column; } if (mHasStableIds) { final long id = mAdapter.getItemId(position); rec.id = id; lp.id = id; } lp.column = nextCol; 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); final int childHeight = child.getMeasuredHeight(); if (invalidateBefore || (childHeight != rec.height && rec.height > 0)) { invalidateLayoutRecordsBeforePosition(position); } rec.height = childHeight; final int startFrom; if (span > 1) { int highest = mItemTops[nextCol]; for (int i = nextCol + 1; i < nextCol + span; i++) { final int top = mItemTops[i]; if (top < highest) { highest = top; } } startFrom = highest; } else { startFrom = mItemTops[nextCol]; } final int childBottom = startFrom; final int childTop = childBottom - childHeight; final int childLeft = paddingLeft + nextCol * (colWidth + itemMargin); final int childRight = childLeft + child.getMeasuredWidth(); child.layout(childLeft, childTop, childRight, childBottom); for (int i = nextCol; i < nextCol + span; i++) { mItemTops[i] = childTop - rec.getMarginAbove(i - nextCol) - itemMargin; } nextCol = getNextColumnUp(); mFirstPosition = position--; } int highestView = getHeight(); for (int i = 0; i < mColCount; i++) { if (mItemTops[i] < highestView) { highestView = mItemTops[i]; } } return gridTop - highestView; }
From source file:cn.ieclipse.af.view.StaggeredGridView.java
/** * Should be called with mPopulating set to true * * @param fromPosition Position to start filling from * @param overhang the number of extra pixels to fill beyond the current bottom edge * @return the max overhang beyond the end of the view of any added items at the bottom */// w w w. j ava 2 s .c o m final int fillDown(int fromPosition, int overhang) { final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int itemMargin = mItemMargin; final int colWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount; final int gridBottom = getHeight() - getPaddingBottom(); final int fillTo = gridBottom + overhang; int nextCol = getNextColumnDown(); int position = fromPosition; while (nextCol >= 0 && mItemBottoms[nextCol] < fillTo && position < mItemCount) { final View child = obtainView(position, null); LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (child.getParent() != this) { if (mInLayout) { addViewInLayout(child, -1, lp); } else { addView(child); } } final int span = Math.min(mColCount, lp.span); final int widthSize = colWidth * span + itemMargin * (span - 1); final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); LayoutRecord rec; if (span > 1) { rec = getNextRecordDown(position, span); nextCol = rec.column; } else { rec = mLayoutRecords.get(position); } boolean invalidateAfter = false; if (rec == null) { rec = new LayoutRecord(); mLayoutRecords.put(position, rec); rec.column = nextCol; rec.span = span; } else if (span != rec.span) { rec.span = span; rec.column = nextCol; invalidateAfter = true; } else { nextCol = rec.column; } if (mHasStableIds) { final long id = mAdapter.getItemId(position); rec.id = id; lp.id = id; } lp.column = nextCol; 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); final int childHeight = child.getMeasuredHeight(); if (invalidateAfter || (childHeight != rec.height && rec.height > 0)) { invalidateLayoutRecordsAfterPosition(position); } rec.height = childHeight; final int startFrom; if (span > 1) { int lowest = mItemBottoms[nextCol]; for (int i = nextCol + 1; i < nextCol + span; i++) { final int bottom = mItemBottoms[i]; if (bottom > lowest) { lowest = bottom; } } startFrom = lowest; } else { startFrom = mItemBottoms[nextCol]; } final int childTop = startFrom + itemMargin; final int childBottom = childTop + childHeight; final int childLeft = paddingLeft + nextCol * (colWidth + itemMargin); final int childRight = childLeft + child.getMeasuredWidth(); child.layout(childLeft, childTop, childRight, childBottom); for (int i = nextCol; i < nextCol + span; i++) { mItemBottoms[i] = childBottom + rec.getMarginBelow(i - nextCol); } nextCol = getNextColumnDown(); position++; } int lowestView = 0; for (int i = 0; i < mColCount; i++) { if (mItemBottoms[i] > lowestView) { lowestView = mItemBottoms[i]; } } return lowestView - gridBottom; }
From source file:com.appunite.list.HorizontalListView.java
/** * Measures the width of the given range of children (inclusive) and * returns the width with this ListView's padding and divider heights * included. If maxWidth is provided, the measuring will stop when the * current width reaches maxWidth./*from w w w .j a v a 2 s . c om*/ * * @param heightMeasureSpec The width measure spec to be given to a child's * {@link android.view.View#measure(int, int)}. * @param startPosition The position of the first child to be shown. * @param endPosition The (inclusive) position of the last child to be * shown. Specify {@link #NO_POSITION} if the last child should be * the last available child from the adapter. * @param maxWidth The maximum width that will be returned (if all the * children don't fit in this value, this value will be * returned). * @param disallowPartialChildPosition In general, whether the returned * width should only contain entire children. This is more * powerful--it is the first inclusive position at which partial * children will not be allowed. Example: it looks nice to have * at least 3 completely visible children, and in portrait this * will most likely fit; but in landscape there could be times * when even 2 children can not be completely shown, so a value * of 2 (remember, inclusive) would be good (assuming * startPosition is 0). * @return The width of this ListView with the given children. */ final int measureWidthOfChildren(int heightMeasureSpec, int startPosition, int endPosition, final int maxWidth, int disallowPartialChildPosition) { final ListAdapter adapter = mAdapter; if (adapter == null) { return mListPadding.left + mListPadding.right; } // Include the padding of the list int returnedWidth = mListPadding.left + mListPadding.right; final int dividerWidth = ((mDividerWidth > 0) && mDivider != null) ? mDividerWidth : 0; // The previous width value that was less than maxWidth and contained // no partial children int prevWidthWithoutPartialChild = 0; int i; View child; // mItemCount - 1 since endPosition parameter is inclusive endPosition = (endPosition == NO_POSITION) ? adapter.getCount() - 1 : endPosition; final RecycleBin recycleBin = mRecycler; final boolean recyle = recycleOnMeasure(); final boolean[] isScrap = mIsScrap; for (i = startPosition; i <= endPosition; ++i) { child = obtainView(i, isScrap); measureScrapChild(child, i, heightMeasureSpec); if (i > 0) { // Count the divider for all but one child returnedWidth += dividerWidth; } // Recycle the view before we possibly return from the method if (recyle && recycleBin.shouldRecycleViewType(((LayoutParams) child.getLayoutParams()).viewType)) { recycleBin.addScrapView(child, -1); } returnedWidth += child.getMeasuredWidth(); if (returnedWidth >= maxWidth) { // We went over, figure out which width to return. If returnedWidth > maxWidth, // then the i'th position did not fit completely. return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1) && (i > disallowPartialChildPosition) // We've past the min pos && (prevWidthWithoutPartialChild > 0) // We have a prev width && (returnedWidth != maxWidth) // i'th child did not fit completely ? prevWidthWithoutPartialChild : maxWidth; } if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) { prevWidthWithoutPartialChild = returnedWidth; } } // At this point, we went through the range of children, and they each // completely fit, so return the returnedWidth return returnedWidth; }
From source file:com.google.android.flexbox.FlexboxLayoutManager.java
private int layoutFlexLineMainAxisHorizontal(FlexLine flexLine, LayoutState layoutState) { assert mFlexboxHelper.mMeasureSpecCache != null; int paddingLeft = getPaddingLeft(); int paddingRight = getPaddingRight(); int parentWidth = getWidth(); int childTop = layoutState.mOffset; if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START) { childTop = childTop - flexLine.mCrossSize; }//ww w. j a v a2 s . c om int startPosition = layoutState.mPosition; float childLeft; // Only used when mIsRtl is true float childRight; float spaceBetweenItem = 0f; switch (mJustifyContent) { case JustifyContent.FLEX_START: childLeft = paddingLeft; childRight = parentWidth - paddingRight; break; case JustifyContent.FLEX_END: childLeft = parentWidth - flexLine.mMainSize + paddingRight; childRight = flexLine.mMainSize - paddingLeft; break; case JustifyContent.CENTER: childLeft = paddingLeft + (parentWidth - flexLine.mMainSize) / 2f; childRight = parentWidth - paddingRight - (parentWidth - flexLine.mMainSize) / 2f; break; case JustifyContent.SPACE_AROUND: if (flexLine.mItemCount != 0) { spaceBetweenItem = (parentWidth - flexLine.mMainSize) / (float) flexLine.mItemCount; } childLeft = paddingLeft + spaceBetweenItem / 2f; childRight = parentWidth - paddingRight - spaceBetweenItem / 2f; break; case JustifyContent.SPACE_BETWEEN: childLeft = paddingLeft; float denominator = flexLine.mItemCount != 1 ? flexLine.mItemCount - 1 : 1f; spaceBetweenItem = (parentWidth - flexLine.mMainSize) / denominator; childRight = parentWidth - paddingRight; break; case JustifyContent.SPACE_EVENLY: if (flexLine.mItemCount != 0) { spaceBetweenItem = (parentWidth - flexLine.mMainSize) / (float) (flexLine.mItemCount + 1); } childLeft = paddingLeft + spaceBetweenItem; childRight = parentWidth - paddingRight - spaceBetweenItem; break; default: throw new IllegalStateException("Invalid justifyContent is set: " + mJustifyContent); } childLeft -= mAnchorInfo.mPerpendicularCoordinate; childRight -= mAnchorInfo.mPerpendicularCoordinate; spaceBetweenItem = Math.max(spaceBetweenItem, 0); // Used only when mLayoutDirection == LayoutState.LAYOUT_START to remember the index // a flex item should be inserted int indexInFlexLine = 0; for (int i = startPosition, itemCount = flexLine.getItemCount(); i < startPosition + itemCount; i++) { View view = getFlexItemAt(i); if (view == null) { continue; } if (layoutState.mLayoutDirection == LayoutState.LAYOUT_END) { calculateItemDecorationsForChild(view, TEMP_RECT); addView(view); } else { calculateItemDecorationsForChild(view, TEMP_RECT); addView(view, indexInFlexLine); indexInFlexLine++; } // Retrieve the measure spec from the cache because the view may be re-created when // retrieved from Recycler, in that case measured width/height are set to 0 even // each visible child should be measured at least once in the FlexboxHelper long measureSpec = mFlexboxHelper.mMeasureSpecCache[i]; int widthSpec = mFlexboxHelper.extractLowerInt(measureSpec); int heightSpec = mFlexboxHelper.extractHigherInt(measureSpec); LayoutParams lp = (LayoutParams) view.getLayoutParams(); if (shouldMeasureChild(view, widthSpec, heightSpec, lp)) { view.measure(widthSpec, heightSpec); } childLeft += (lp.leftMargin + getLeftDecorationWidth(view)); childRight -= (lp.rightMargin + getRightDecorationWidth(view)); int topWithDecoration = childTop + getTopDecorationHeight(view); if (mIsRtl) { mFlexboxHelper.layoutSingleChildHorizontal(view, flexLine, Math.round(childRight) - view.getMeasuredWidth(), topWithDecoration, Math.round(childRight), topWithDecoration + view.getMeasuredHeight()); } else { mFlexboxHelper.layoutSingleChildHorizontal(view, flexLine, Math.round(childLeft), topWithDecoration, Math.round(childLeft) + view.getMeasuredWidth(), topWithDecoration + view.getMeasuredHeight()); } childLeft += (view.getMeasuredWidth() + lp.rightMargin + getRightDecorationWidth(view) + spaceBetweenItem); childRight -= (view.getMeasuredWidth() + lp.leftMargin + getLeftDecorationWidth(view) + spaceBetweenItem); } layoutState.mFlexLinePosition += mLayoutState.mLayoutDirection; return flexLine.getCrossSize(); }
From source file:com.devabit.takestock.ui.widget.FlexboxLayout.java
/** * Sub method for {@link #onMeasure(int, int)} when the main axis direction is vertical * (either from top to bottom or bottom to top). * * @param widthMeasureSpec horizontal space requirements as imposed by the parent * @param heightMeasureSpec vertical space requirements as imposed by the parent * @see #onMeasure(int, int)/*w w w . j av a 2 s . co m*/ * @see #setFlexDirection(int) * @see #setFlexWrap(int) * @see #setAlignItems(int) * @see #setAlignContent(int) */ private void measureVertical(int widthMeasureSpec, int heightMeasureSpec) { int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int childState = 0; mFlexLines.clear(); // Determine how many flex lines are needed in this layout by measuring each child. // (Expand or shrink the view depending on the flexGrow and flexShrink attributes in a later // loop) int childCount = getChildCount(); int paddingTop = getPaddingTop(); int paddingBottom = getPaddingBottom(); int largestWidthInColumn = Integer.MIN_VALUE; FlexLine flexLine = new FlexLine(); flexLine.mainSize = paddingTop + paddingBottom; for (int i = 0; i < childCount; i++) { View child = getReorderedChildAt(i); if (child == null) { addFlexLineIfLastFlexItem(i, childCount, flexLine); continue; } else if (child.getVisibility() == View.GONE) { flexLine.itemCount++; addFlexLineIfLastFlexItem(i, childCount, flexLine); continue; } FlexboxLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp.alignSelf == LayoutParams.ALIGN_SELF_STRETCH) { flexLine.indicesAlignSelfStretch.add(i); } int childHeight = lp.height; if (lp.flexBasisPercent != LayoutParams.FLEX_BASIS_PERCENT_DEFAULT && heightMode == MeasureSpec.EXACTLY) { childHeight = Math.round(heightSize * lp.flexBasisPercent); // Use the dimension from the layout_height attribute if the heightMode is not // MeasureSpec.EXACTLY even if any fraction value is set to layout_flexBasisPercent. // There are likely quite few use cases where assigning any fraction values // with heightMode is not MeasureSpec.EXACTLY (e.g. FlexboxLayout's layout_height // is set to wrap_content) } int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin, lp.width); int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin, childHeight); child.measure(childWidthMeasureSpec, childHeightMeasureSpec); // Check the size constraint after the first measurement for the child // To prevent the child's width/height violate the size constraints imposed by the // {@link LayoutParams#minWidth}, {@link LayoutParams#minHeight}, // {@link LayoutParams#maxWidth} and {@link LayoutParams#maxHeight} attributes. // E.g. When the child's layout_height is wrap_content the measured height may be // less than the min height after the first measurement. checkSizeConstraints(child); childState = ViewCompat.combineMeasuredStates(childState, ViewCompat.getMeasuredState(child)); largestWidthInColumn = Math.max(largestWidthInColumn, child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); if (isWrapRequired(mFlexWrap, heightMode, heightSize, flexLine.mainSize, child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin, lp)) { if (flexLine.itemCount > 0) { mFlexLines.add(flexLine); } flexLine = new FlexLine(); flexLine.itemCount = 1; flexLine.mainSize = paddingTop + paddingBottom; largestWidthInColumn = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; } else { flexLine.itemCount++; } flexLine.mainSize += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; flexLine.totalFlexGrow += lp.flexGrow; flexLine.totalFlexShrink += lp.flexShrink; // Temporarily set the cross axis length as the largest child width in the column // Expand along the cross axis depending on the mAlignContent property if needed // later flexLine.crossSize = Math.max(flexLine.crossSize, largestWidthInColumn); addFlexLineIfLastFlexItem(i, childCount, flexLine); } determineMainSize(mFlexDirection, widthMeasureSpec, heightMeasureSpec); determineCrossSize(mFlexDirection, widthMeasureSpec, heightMeasureSpec, getPaddingLeft() + getPaddingRight()); // Now cross size for each flex line is determined. // Expand the views if alignItems (or alignSelf in each child view) is set to stretch stretchViews(mFlexDirection, mAlignItems); setMeasuredDimensionForFlex(mFlexDirection, widthMeasureSpec, heightMeasureSpec, childState); }