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.app.afteryou.ui.staggered.StaggeredGridView.java
/** * Should be called with mPopulating set to true * /*ww w. ja v a 2 s .com*/ * @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 */ 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; mColWidth = colWidth; final int gridTop = getPaddingTop(); final int fillTo = gridTop - overhang; int nextCol = getNextColumnUp(); int position = fromPosition; while (nextCol >= 0 && mItemTops[nextCol] > fillTo && position >= 0) { // make sure the nextCol is correct. check to see if has been mapped // otherwise stick to getNextColumnUp() if (!mColMappings.get(nextCol).contains((Integer) position)) { for (int i = 0; i < mColMappings.size(); i++) { if (mColMappings.get(i).contains((Integer) position)) { nextCol = i; break; } } } final View child = obtainView(position, null); if (child == null) continue; LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null) { lp = generateDefaultLayoutParams(); child.setLayoutParams(lp); } if (child.getParent() != this) { addViewInLayout(child, 0, lp); } 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; //TODO } 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; //TODO } 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; int itemTop = mItemTops[nextCol]; 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++) { final View child = getFirstChildAtColumn(i); if (child == null) { highestView = 0; break; } final int top = child.getTop(); if (top < highestView) { highestView = top; } } return gridTop - highestView; }
From source file:cn.iterlog.myapplication.widget.overscroll.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 *///from w ww. j a va 2 s .co 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(fromPosition); int position = fromPosition; while (nextCol >= 0 && mItemBottoms[nextCol] < fillTo && position < mItemCount) { final View child = obtainView(position, null); if (child == null) continue; LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null) { lp = this.generateDefaultLayoutParams(); child.setLayoutParams(lp); } 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); // add the position to the mapping Integer positionInt = Integer.valueOf(position); if (!mColMappings.get(nextCol).contains(positionInt)) { // check to see if the mapping exists in other columns // this would happen if list has been updated for (HashSet<Integer> cols : mColMappings) { cols.remove(positionInt); } mColMappings.get(nextCol).add(positionInt); } for (int i = nextCol; i < nextCol + span; i++) { mItemBottoms[i] = childBottom + rec.getMarginBelow(i - nextCol); } position++; 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:cc.flydev.launcher.Page.java
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!mIsDataReady || getChildCount() == 0) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); return;//from w ww .j a v a 2s.c o m } // We measure the dimensions of the PagedView to be larger than the pages so that when we // zoom out (and scale down), the view is still contained in the parent int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); // NOTE: We multiply by 1.5f to account for the fact that depending on the offset of the // viewport, we can be at most one and a half screens offset once we scale down DisplayMetrics dm = getResources().getDisplayMetrics(); int maxSize = Math.max(dm.widthPixels, dm.heightPixels + mInsets.top + mInsets.bottom); int parentWidthSize, parentHeightSize; int scaledWidthSize, scaledHeightSize; if (mUseMinScale) { parentWidthSize = (int) (1.5f * maxSize); parentHeightSize = maxSize; scaledWidthSize = (int) (parentWidthSize / mMinScale); scaledHeightSize = (int) (parentHeightSize / mMinScale); } else { scaledWidthSize = widthSize; scaledHeightSize = heightSize; } mViewport.set(0, 0, widthSize, heightSize); if (widthMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.UNSPECIFIED) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); return; } // Return early if we aren't given a proper dimension if (widthSize <= 0 || heightSize <= 0) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); return; } /* Allow the height to be set as WRAP_CONTENT. This allows the particular case * of the All apps view on XLarge displays to not take up more space then it needs. Width * is still not allowed to be set as WRAP_CONTENT since many parts of the code expect * each page to have the same width. */ final int verticalPadding = getPaddingTop() + getPaddingBottom(); final int horizontalPadding = getPaddingLeft() + getPaddingRight(); // The children are given the same width and height as the workspace // unless they were set to WRAP_CONTENT if (DEBUG) Log.d(TAG, "PagedView.onMeasure(): " + widthSize + ", " + heightSize); if (DEBUG) Log.d(TAG, "PagedView.scaledSize: " + scaledWidthSize + ", " + scaledHeightSize); if (DEBUG) Log.d(TAG, "PagedView.parentSize: " + parentWidthSize + ", " + parentHeightSize); if (DEBUG) Log.d(TAG, "PagedView.horizontalPadding: " + horizontalPadding); if (DEBUG) Log.d(TAG, "PagedView.verticalPadding: " + verticalPadding); final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { // disallowing padding in paged view (just pass 0) final View child = getPageAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); int childWidthMode; int childHeightMode; int childWidth; int childHeight; if (!lp.isFullScreenPage) { if (lp.width == LayoutParams.WRAP_CONTENT) { childWidthMode = MeasureSpec.AT_MOST; } else { childWidthMode = MeasureSpec.EXACTLY; } if (lp.height == LayoutParams.WRAP_CONTENT) { childHeightMode = MeasureSpec.AT_MOST; } else { childHeightMode = MeasureSpec.EXACTLY; } childWidth = widthSize - horizontalPadding; childHeight = heightSize - verticalPadding - mInsets.top - mInsets.bottom; mNormalChildHeight = childHeight; } else { childWidthMode = MeasureSpec.EXACTLY; childHeightMode = MeasureSpec.EXACTLY; if (mUseMinScale) { childWidth = getViewportWidth(); childHeight = getViewportHeight(); } else { childWidth = widthSize - getPaddingLeft() - getPaddingRight(); childHeight = heightSize - getPaddingTop() - getPaddingBottom(); } } final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth, childWidthMode); final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight, childHeightMode); child.measure(childWidthMeasureSpec, childHeightMeasureSpec); } } setMeasuredDimension(scaledWidthSize, scaledHeightSize); if (childCount > 0) { // Calculate the variable page spacing if necessary if (mAutoComputePageSpacing && mRecomputePageSpacing) { // The gap between pages in the PagedView should be equal to the gap from the page // to the edge of the screen (so it is not visible in the current screen). To // account for unequal padding on each side of the paged view, we take the maximum // of the left/right gap and use that as the gap between each page. int offset = (getViewportWidth() - getChildWidth(0)) / 2; int spacing = Math.max(offset, widthSize - offset - getChildAt(0).getMeasuredWidth()); setPageSpacing(spacing); mRecomputePageSpacing = false; } } }
From source file:com.albedinsky.android.support.ui.widget.ViewPager.java
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // For simple implementation, our internal size is always 0. // We depend on the container to specify the layout size of // our view. We can't really know what it is since we will be // adding and removing different arbitrary views and do not // want the layout to change as this happens. setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec)); final int measuredWidth = getMeasuredWidth(); final int maxGutterSize = measuredWidth / 10; mGutterSize = Math.min(maxGutterSize, mDefaultGutterSize); // Children are just made to fill our space. int childWidthSize = measuredWidth - getPaddingLeft() - getPaddingRight(); int childHeightSize = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); /*//from w w w. j a v a 2s . c om * Make sure all children have been properly measured. Decor views first. * Right now we cheat and make this less complicated by assuming decor * views won't intersect. We will pin to edges based on gravity. */ int size = getChildCount(); for (int i = 0; i < size; ++i) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp != null && lp.isDecor) { final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK; final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; int widthMode = MeasureSpec.AT_MOST; int heightMode = MeasureSpec.AT_MOST; boolean consumeVertical = vgrav == Gravity.TOP || vgrav == Gravity.BOTTOM; boolean consumeHorizontal = hgrav == Gravity.LEFT || hgrav == Gravity.RIGHT; if (consumeVertical) { widthMode = MeasureSpec.EXACTLY; } else if (consumeHorizontal) { heightMode = MeasureSpec.EXACTLY; } int widthSize = childWidthSize; int heightSize = childHeightSize; if (lp.width != LayoutParams.WRAP_CONTENT) { widthMode = MeasureSpec.EXACTLY; if (lp.width != LayoutParams.FILL_PARENT) { widthSize = lp.width; } } if (lp.height != LayoutParams.WRAP_CONTENT) { heightMode = MeasureSpec.EXACTLY; if (lp.height != LayoutParams.FILL_PARENT) { heightSize = lp.height; } } final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode); final int heightSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode); child.measure(widthSpec, heightSpec); if (consumeVertical) { childHeightSize -= child.getMeasuredHeight(); } else if (consumeHorizontal) { childWidthSize -= child.getMeasuredWidth(); } } } } mChildWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY); mChildHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeightSize, MeasureSpec.EXACTLY); // Make sure we have created all fragments that we need to have shown. mInLayout = true; populate(); mInLayout = false; // Page views next. size = getChildCount(); for (int i = 0; i < size; ++i) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { if (DEBUG_ENABLED) Log.v(TAG, "Measuring #" + i + " " + child + ": " + mChildWidthMeasureSpec); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null || !lp.isDecor) { final int widthSpec = MeasureSpec.makeMeasureSpec((int) (childWidthSize * lp.widthFactor), MeasureSpec.EXACTLY); child.measure(widthSpec, mChildHeightMeasureSpec); } } } }
From source file:com.biznow.ordernow.fragments.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 *///from w w w .j a v a 2s.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(fromPosition); int position = fromPosition; while (nextCol >= 0 && mItemBottoms[nextCol] < fillTo && position < mItemCount) { final View child = obtainView(position, null); if (child == null) continue; LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null) { lp = this.generateDefaultLayoutParams(); child.setLayoutParams(lp); } 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); // add the position to the mapping if (!mColMappings.get(nextCol).contains(position)) { // check to see if the mapping exists in other columns // this would happen if list has been updated for (ArrayList<Integer> list : mColMappings) { if (list.contains(position)) { list.remove((Integer) position); } } mColMappings.get(nextCol).add(position); } for (int i = nextCol; i < nextCol + span; i++) { mItemBottoms[i] = childBottom + rec.getMarginBelow(i - nextCol); } position++; 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:VerticalViewPager.java
@SuppressWarnings("deprecation") @Override//from w w w. j a v a 2s. c om protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // For simple implementation, our internal size is always 0. // We depend on the container to specify the layout size of // our view. We can't really know what it is since we will be // adding and removing different arbitrary views and do not // want the layout to change as this happens. setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec)); final int measuredWidth = getMeasuredWidth(); final int measuredHeight = getMeasuredHeight(); final int maxGutterSize = measuredHeight / 10; mGutterSize = Math.min(maxGutterSize, mDefaultGutterSize); // Children are just made to fill our space. int childWidthSize = measuredWidth - getPaddingLeft() - getPaddingRight(); int childHeightSize = measuredHeight - getPaddingTop() - getPaddingBottom(); /* * Make sure all children have been properly measured. Decor views first. * Right now we cheat and make this less complicated by assuming decor * views won't intersect. We will pin to edges based on gravity. */ int size = getChildCount(); for (int i = 0; i < size; ++i) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp != null && lp.isDecor) { final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK; final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; int widthMode = MeasureSpec.AT_MOST; int heightMode = MeasureSpec.AT_MOST; boolean consumeVertical = vgrav == Gravity.TOP || vgrav == Gravity.BOTTOM; boolean consumeHorizontal = hgrav == Gravity.LEFT || hgrav == Gravity.RIGHT; if (consumeVertical) { widthMode = MeasureSpec.EXACTLY; } else if (consumeHorizontal) { heightMode = MeasureSpec.EXACTLY; } int widthSize = childWidthSize; int heightSize = childHeightSize; if (lp.width != LayoutParams.WRAP_CONTENT) { widthMode = MeasureSpec.EXACTLY; if (lp.width != LayoutParams.FILL_PARENT) { widthSize = lp.width; } } if (lp.height != LayoutParams.WRAP_CONTENT) { heightMode = MeasureSpec.EXACTLY; if (lp.height != LayoutParams.FILL_PARENT) { heightSize = lp.height; } } final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode); final int heightSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode); child.measure(widthSpec, heightSpec); if (consumeVertical) { childHeightSize -= child.getMeasuredHeight(); } else if (consumeHorizontal) { childWidthSize -= child.getMeasuredWidth(); } } } } mChildWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY); mChildHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeightSize, MeasureSpec.EXACTLY); // Make sure we have created all fragments that we need to have shown. mInLayout = true; populate(); mInLayout = false; // Page views next. size = getChildCount(); for (int i = 0; i < size; ++i) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { if (DEBUG) Log.v(TAG, "Measuring #" + i + " " + child + ": " + mChildWidthMeasureSpec); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null || !lp.isDecor) { final int heightSpec = MeasureSpec.makeMeasureSpec((int) (childHeightSize * lp.heightFactor), MeasureSpec.EXACTLY); child.measure(mChildWidthMeasureSpec, heightSpec); } } } }
From source file:com.google.android.flexbox.FlexboxLayout.java
/** * Shrink the flex items along the main axis based on the individual flexShrink attribute. * * @param flexLine the flex line to which flex items belong * @param flexDirection the flexDirection value for this FlexboxLayout * @param maxMainSize the maximum main size. Shrank main size will be this size * @param paddingAlongMainAxis the padding value along the main axis * @param startIndex the start index of the children views to be shrank. This index * needs to/*from ww w. jav a2s . c om*/ * be an absolute index in the flex container (FlexboxLayout), * not the relative index in the flex line. * @return the next index, the next flex line's first flex item starts from the returned index * @see #getFlexDirection() * @see #setFlexDirection(int) * @see LayoutParams#flexShrink */ private int shrinkFlexItems(FlexLine flexLine, @FlexDirection int flexDirection, int maxMainSize, int paddingAlongMainAxis, int startIndex) { int childIndex = startIndex; int sizeBeforeShrink = flexLine.mMainSize; if (flexLine.mTotalFlexShrink <= 0 || maxMainSize > flexLine.mMainSize) { childIndex += flexLine.mItemCount; return childIndex; } boolean needsReshrink = false; float unitShrink = (flexLine.mMainSize - maxMainSize) / flexLine.mTotalFlexShrink; float accumulatedRoundError = 0; flexLine.mMainSize = paddingAlongMainAxis + flexLine.mDividerLengthInMainSize; for (int i = 0; i < flexLine.mItemCount; i++) { View child = getReorderedChildAt(childIndex); if (child == null) { continue; } else if (child.getVisibility() == View.GONE) { childIndex++; continue; } LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (isMainAxisDirectionHorizontal(flexDirection)) { // The direction of main axis is horizontal if (!mChildrenFrozen[childIndex]) { float rawCalculatedWidth = child.getMeasuredWidth() - unitShrink * lp.flexShrink; if (i == flexLine.mItemCount - 1) { rawCalculatedWidth += accumulatedRoundError; accumulatedRoundError = 0; } int newWidth = Math.round(rawCalculatedWidth); if (newWidth < lp.minWidth) { // This means the child doesn't have enough space to distribute the negative // free space. To adjust the flex line length down to the maxMainSize, remaining // negative free space needs to be re-distributed to other flex items // (children views). In that case, invoke this method again with the same // startIndex. needsReshrink = true; newWidth = lp.minWidth; mChildrenFrozen[childIndex] = true; flexLine.mTotalFlexShrink -= lp.flexShrink; } else { accumulatedRoundError += (rawCalculatedWidth - newWidth); if (accumulatedRoundError > 1.0) { newWidth += 1; accumulatedRoundError -= 1; } else if (accumulatedRoundError < -1.0) { newWidth -= 1; accumulatedRoundError += 1; } } child.measure(MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), MeasureSpec.EXACTLY)); } flexLine.mMainSize += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; } else { // The direction of main axis is vertical if (!mChildrenFrozen[childIndex]) { float rawCalculatedHeight = child.getMeasuredHeight() - unitShrink * lp.flexShrink; if (i == flexLine.mItemCount - 1) { rawCalculatedHeight += accumulatedRoundError; accumulatedRoundError = 0; } int newHeight = Math.round(rawCalculatedHeight); if (newHeight < lp.minHeight) { // Need to invoke this method again like the case flex direction is vertical needsReshrink = true; newHeight = lp.minHeight; mChildrenFrozen[childIndex] = true; flexLine.mTotalFlexShrink -= lp.flexShrink; } else { accumulatedRoundError += (rawCalculatedHeight - newHeight); if (accumulatedRoundError > 1.0) { newHeight += 1; accumulatedRoundError -= 1; } else if (accumulatedRoundError < -1.0) { newHeight -= 1; accumulatedRoundError += 1; } } child.measure(MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY)); } flexLine.mMainSize += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; } childIndex++; } if (needsReshrink && sizeBeforeShrink != flexLine.mMainSize) { // Re-invoke the method with the same startIndex to distribute the negative free space // that wasn't fully distributed (because some views length were not enough) shrinkFlexItems(flexLine, flexDirection, maxMainSize, paddingAlongMainAxis, startIndex); } return childIndex; }
From source file:com.google.android.flexbox.FlexboxLayout.java
/** * Expand the flex items along the main axis based on the individual flexGrow attribute. * * @param flexLine the flex line to which flex items belong * @param flexDirection the flexDirection value for this FlexboxLayout * @param maxMainSize the maximum main size. Expanded main size will be this size * @param paddingAlongMainAxis the padding value along the main axis * @param startIndex the start index of the children views to be expanded. This index * needs to// www. ja va 2 s. c o m * be an absolute index in the flex container (FlexboxLayout), * not the relative index in the flex line. * @return the next index, the next flex line's first flex item starts from the returned index * @see #getFlexDirection() * @see #setFlexDirection(int) * @see LayoutParams#flexGrow */ private int expandFlexItems(FlexLine flexLine, @FlexDirection int flexDirection, int maxMainSize, int paddingAlongMainAxis, int startIndex) { int childIndex = startIndex; if (flexLine.mTotalFlexGrow <= 0 || maxMainSize < flexLine.mMainSize) { childIndex += flexLine.mItemCount; return childIndex; } int sizeBeforeExpand = flexLine.mMainSize; boolean needsReexpand = false; float unitSpace = (maxMainSize - flexLine.mMainSize) / flexLine.mTotalFlexGrow; flexLine.mMainSize = paddingAlongMainAxis + flexLine.mDividerLengthInMainSize; float accumulatedRoundError = 0; for (int i = 0; i < flexLine.mItemCount; i++) { View child = getReorderedChildAt(childIndex); if (child == null) { continue; } else if (child.getVisibility() == View.GONE) { childIndex++; continue; } LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (isMainAxisDirectionHorizontal(flexDirection)) { // The direction of the main axis is horizontal if (!mChildrenFrozen[childIndex]) { float rawCalculatedWidth = child.getMeasuredWidth() + unitSpace * lp.flexGrow; if (i == flexLine.mItemCount - 1) { rawCalculatedWidth += accumulatedRoundError; accumulatedRoundError = 0; } int newWidth = Math.round(rawCalculatedWidth); if (newWidth > lp.maxWidth) { // This means the child can't expand beyond the value of the maxWidth attribute. // To adjust the flex line length to the size of maxMainSize, remaining // positive free space needs to be re-distributed to other flex items // (children views). In that case, invoke this method again with the same // startIndex. needsReexpand = true; newWidth = lp.maxWidth; mChildrenFrozen[childIndex] = true; flexLine.mTotalFlexGrow -= lp.flexGrow; } else { accumulatedRoundError += (rawCalculatedWidth - newWidth); if (accumulatedRoundError > 1.0) { newWidth += 1; accumulatedRoundError -= 1.0; } else if (accumulatedRoundError < -1.0) { newWidth -= 1; accumulatedRoundError += 1.0; } } child.measure(MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), MeasureSpec.EXACTLY)); } flexLine.mMainSize += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; } else { // The direction of the main axis is vertical if (!mChildrenFrozen[childIndex]) { float rawCalculatedHeight = child.getMeasuredHeight() + unitSpace * lp.flexGrow; if (i == flexLine.mItemCount - 1) { rawCalculatedHeight += accumulatedRoundError; accumulatedRoundError = 0; } int newHeight = Math.round(rawCalculatedHeight); if (newHeight > lp.maxHeight) { // This means the child can't expand beyond the value of the maxHeight // attribute. // To adjust the flex line length to the size of maxMainSize, remaining // positive free space needs to be re-distributed to other flex items // (children views). In that case, invoke this method again with the same // startIndex. needsReexpand = true; newHeight = lp.maxHeight; mChildrenFrozen[childIndex] = true; flexLine.mTotalFlexGrow -= lp.flexGrow; } else { accumulatedRoundError += (rawCalculatedHeight - newHeight); if (accumulatedRoundError > 1.0) { newHeight += 1; accumulatedRoundError -= 1.0; } else if (accumulatedRoundError < -1.0) { newHeight -= 1; accumulatedRoundError += 1.0; } } child.measure(MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY)); } flexLine.mMainSize += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; } childIndex++; } if (needsReexpand && sizeBeforeExpand != flexLine.mMainSize) { // Re-invoke the method with the same startIndex to distribute the positive free space // that wasn't fully distributed (because of maximum length constraint) expandFlexItems(flexLine, flexDirection, maxMainSize, paddingAlongMainAxis, startIndex); } return childIndex; }
From source file:com.example.uidemo.widget.waterfall.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; mColWidth = colWidth; final int gridTop = getPaddingTop(); final int fillTo = gridTop - overhang; int nextCol = getNextColumnUp(); int position = fromPosition; while (nextCol >= 0 && mItemTops[nextCol] > fillTo && position >= 0) { // make sure the nextCol is correct. check to see if has been mapped // otherwise stick to getNextColumnUp() if (!mColMappings.get(nextCol).contains((Integer) position)) { for (int i = 0; i < mColMappings.size(); i++) { if (mColMappings.get(i).contains((Integer) position)) { nextCol = i; break; } } } // displayMapping(); final View child = obtainView(position, null); if (child == null) continue; LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null) { lp = this.generateDefaultLayoutParams(); child.setLayoutParams(lp); } 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; int itemTop = mItemTops[nextCol]; 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]; } int childBottom = startFrom; int childTop = childBottom - childHeight; final int childLeft = paddingLeft + nextCol * (colWidth + itemMargin); final int childRight = childLeft + child.getMeasuredWidth(); // if(position == 0){ // if(this.getChildCount()>1 && this.mColCount>1){ // childTop = this.getChildAt(1).getTop(); // childBottom = childTop + childHeight; // } // } 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++) { final View child = getFirstChildAtColumn(i); if (child == null) { highestView = 0; break; } final int top = child.getTop(); if (top < highestView) { highestView = top; } } return gridTop - highestView; }
From source file:com.autoscrollloopviewpager.widget.LoopViewPager.java
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // For simple implementation, our internal size is always 0. // We depend on the container to specify the layout size of // our view. We can't really know what it is since we will be // adding and removing different arbitrary views and do not // want the layout to change as this happens. setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec)); final int measuredWidth = getMeasuredWidth(); final int maxGutterSize = measuredWidth / 10; mGutterSize = Math.min(maxGutterSize, mDefaultGutterSize); // Children are just made to fill our space. int childWidthSize = measuredWidth - getPaddingLeft() - getPaddingRight(); int childHeightSize = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); /*/*w w w. ja v a 2s . c o m*/ * Make sure all children have been properly measured. Decor views first. * Right now we cheat and make this less complicated by assuming decor * views won't intersect. We will pin to edges based on gravity. */ int size = getChildCount(); for (int i = 0; i < size; ++i) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp != null && lp.isDecor) { final int hgrav = lp.gravity & Gravity.HORIZONTAL_GRAVITY_MASK; final int vgrav = lp.gravity & Gravity.VERTICAL_GRAVITY_MASK; int widthMode = MeasureSpec.AT_MOST; int heightMode = MeasureSpec.AT_MOST; boolean consumeVertical = vgrav == Gravity.TOP || vgrav == Gravity.BOTTOM; boolean consumeHorizontal = hgrav == Gravity.LEFT || hgrav == Gravity.RIGHT; if (consumeVertical) { widthMode = MeasureSpec.EXACTLY; } else if (consumeHorizontal) { heightMode = MeasureSpec.EXACTLY; } int widthSize = childWidthSize; int heightSize = childHeightSize; if (lp.width != LayoutParams.WRAP_CONTENT) { widthMode = MeasureSpec.EXACTLY; if (lp.width != LayoutParams.FILL_PARENT) { widthSize = lp.width; } } if (lp.height != LayoutParams.WRAP_CONTENT) { heightMode = MeasureSpec.EXACTLY; if (lp.height != LayoutParams.FILL_PARENT) { heightSize = lp.height; } } final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode); final int heightSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode); child.measure(widthSpec, heightSpec); if (consumeVertical) { childHeightSize -= child.getMeasuredHeight(); } else if (consumeHorizontal) { childWidthSize -= child.getMeasuredWidth(); } } } } mChildWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY); mChildHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeightSize, MeasureSpec.EXACTLY); // Make sure we have created all fragments that we need to have shown. mInLayout = true; populate(); mInLayout = false; // Page views next. size = getChildCount(); for (int i = 0; i < size; ++i) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { if (DEBUG) Log.v(TAG, "Measuring #" + i + " " + child + ": " + mChildWidthMeasureSpec); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp == null || !lp.isDecor) { final int widthSpec = MeasureSpec.makeMeasureSpec((int) (childWidthSize * lp.widthFactor), MeasureSpec.EXACTLY); child.measure(widthSpec, mChildHeightMeasureSpec); } } } }