Example usage for android.view View getMeasuredHeight

List of usage examples for android.view View getMeasuredHeight

Introduction

In this page you can find the example usage for android.view View getMeasuredHeight.

Prototype

public final int getMeasuredHeight() 

Source Link

Document

Like #getMeasuredHeightAndState() , but only returns the raw height component (that is the result is masked by #MEASURED_SIZE_MASK ).

Usage

From source file:com.example.leelay.galleyviewpager.GalleyViewPager.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()) - mEndWidth - mPageMargin;
    int childHeightSize = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();

    /*/*from   w ww . j ava2s . 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);
            }
        }
    }
}

From source file:android.support.designox.widget.CoordinatorLayout.java

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    prepareChildren();//from   ww  w.  j  ava2 s.  c  o  m
    ensurePreDrawListener();

    final int paddingLeft = getPaddingLeft();
    final int paddingTop = getPaddingTop();
    final int paddingRight = getPaddingRight();
    final int paddingBottom = getPaddingBottom();
    final int layoutDirection = ViewCompat.getLayoutDirection(this);
    final boolean isRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
    final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    final int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    final int widthPadding = paddingLeft + paddingRight;
    final int heightPadding = paddingTop + paddingBottom;
    int widthUsed = getSuggestedMinimumWidth();
    int heightUsed = getSuggestedMinimumHeight();
    int childState = 0;

    final boolean applyInsets = mLastInsets != null && ViewCompat.getFitsSystemWindows(this);

    final int childCount = mDependencySortedChildren.size();
    for (int i = 0; i < childCount; i++) {
        final View child = mDependencySortedChildren.get(i);
        final LayoutParams lp = (LayoutParams) child.getLayoutParams();

        int keylineWidthUsed = 0;
        if (lp.keyline >= 0 && widthMode != MeasureSpec.UNSPECIFIED) {
            final int keylinePos = getKeyline(lp.keyline);
            final int keylineGravity = GravityCompat.getAbsoluteGravity(resolveKeylineGravity(lp.gravity),
                    layoutDirection) & Gravity.HORIZONTAL_GRAVITY_MASK;
            if ((keylineGravity == Gravity.LEFT && !isRtl) || (keylineGravity == Gravity.RIGHT && isRtl)) {
                keylineWidthUsed = Math.max(0, widthSize - paddingRight - keylinePos);
            } else if ((keylineGravity == Gravity.RIGHT && !isRtl)
                    || (keylineGravity == Gravity.LEFT && isRtl)) {
                keylineWidthUsed = Math.max(0, keylinePos - paddingLeft);
            }
        }

        int childWidthMeasureSpec = widthMeasureSpec;
        int childHeightMeasureSpec = heightMeasureSpec;
        if (applyInsets && !ViewCompat.getFitsSystemWindows(child)) {
            // We're set to handle insets but this child isn't, so we will measure the
            // child as if there are no insets
            final int horizInsets = mLastInsets.getSystemWindowInsetLeft()
                    + mLastInsets.getSystemWindowInsetRight();
            final int vertInsets = mLastInsets.getSystemWindowInsetTop()
                    + mLastInsets.getSystemWindowInsetBottom();

            childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize - horizInsets, widthMode);
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize - vertInsets, heightMode);
        }

        final Behavior b = lp.getBehavior();
        if (b == null || !b.onMeasureChild(this, child, childWidthMeasureSpec, keylineWidthUsed,
                childHeightMeasureSpec, 0)) {
            onMeasureChild(child, childWidthMeasureSpec, keylineWidthUsed, childHeightMeasureSpec, 0);
        }

        widthUsed = Math.max(widthUsed,
                widthPadding + child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);

        heightUsed = Math.max(heightUsed,
                heightPadding + child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
        childState = ViewCompat.combineMeasuredStates(childState, ViewCompat.getMeasuredState(child));
    }

    final int width = ViewCompat.resolveSizeAndState(widthUsed, widthMeasureSpec,
            childState & ViewCompat.MEASURED_STATE_MASK);
    final int height = ViewCompat.resolveSizeAndState(heightUsed, heightMeasureSpec,
            childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
    setMeasuredDimension(width, height);
}

From source file:com.android.backups.StaggeredGridViewByJaumo.java

/**
 * Should be called with mPopulating set to true
 * //from   w  w w.jav  a2  s .co m
 * @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();
    mColWidth = getColWidth(fromPosition);
    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(position)) {
            for (int i = 0; i < mColMappings.size(); i++) {
                if (mColMappings.get(i).contains(position)) {
                    nextCol = i;
                    break;
                }
            }
        }

        final View child = obtainView(position, null);

        if (child == null)
            continue;

        LayoutParams lp = (LayoutParams) child.getLayoutParams();

        if (child.getParent() != this) {
            if (mInLayout) {
                addViewInLayout(child, 0, lp);
            } else {
                addView(child, 0);
            }
        }

        final int itemMargin = getItemMargin(lp.position);
        final int colWidth = getColWidth(lp.position);
        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 = 0;
        } 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;
        }

        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 lowest = mItemTops[nextCol];
            final int colEnd = Math.min(mColCount, nextCol + lp.span);
            for (int i = nextCol; i < colEnd; i++) {
                final int top = mItemTops[i];
                if (top < lowest) {
                    lowest = top;
                }
            }
            startFrom = lowest;
        } else {
            startFrom = mItemTops[nextCol];
        }

        int childBottom = startFrom;
        int childTop = childBottom - childHeight;
        final int childLeft = paddingLeft + itemMargin + nextCol * (colWidth + itemMargin);
        final int childRight = childLeft + child.getMeasuredWidth();

        child.layout(childLeft, childTop, childRight, childBottom);

        final int colEnd = Math.min(mColCount, nextCol + lp.span);
        for (int i = nextCol; i < colEnd; i++) {
            mItemTops[i] = childTop - itemMargin;
        }

        nextCol = getNextColumnUp();
        mFirstPosition = position--;
    }

    int highestView = getHeight();

    for (int i = 0; i < getChildCount(); i++) {
        final View child = getChildAt(i);
        if (child == null) {
            break;
        }
        final int top = child.getTop();

        if (top < highestView) {
            highestView = top;
        }
    }

    return gridTop - highestView;
}

From source file:chan.android.app.bitwise.util.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 ww  . j a  v  a  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;
            nextCol = 0;
        } 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;

        /**
         * Magic does not exist
         */
        //            child.measure(MeasureSpec.EXACTLY, MeasureSpec.UNSPECIFIED);

        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];

            //                final int colEnd = Math.min(mColCount, nextCol + lp.span);
            // Only for span = maxCol
            for (int i = 0; i < mColCount; 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;
        if (span > 1) {
            childLeft = paddingLeft;
        } else {
            childLeft = paddingLeft + nextCol * (colWidth + itemMargin);
        }
        final int childRight = childLeft + child.getMeasuredWidth();
        child.layout(childLeft, childTop, childRight, childBottom);

        rec.left = childLeft;
        rec.top = childTop;
        rec.right = childRight;
        rec.bottom = childBottom;
        rec.hasRecRecord = true;

        // 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);
        }

        final int colEnd = Math.min(mColCount, nextCol + lp.span);
        for (int i = nextCol; i < colEnd; 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:caesar.feng.framework.widget.StaggeredGrid.ExtendableListView.java

/**
 * Add a view as a child and make sure it is measured (if necessary) and
 * positioned properly./*w w w.ja v  a  2s  .com*/
 *
 * @param child    The view to add
 * @param position The position of this child
 * @param y        The y position relative to which this view will be positioned
 * @param flowDown If true, align top edge to y. If false, align bottom
 *                 edge to y.
 * @param selected Is this position selected?
 * @param recycled Has this view been pulled from the recycle bin? If so it
 *                 does not need to be remeasured.
 */
private void setupChild(View child, int position, int y, boolean flowDown, boolean selected, boolean recycled) {
    final boolean isSelected = false; // TODO : selected && shouldShowSelector();
    final boolean updateChildSelected = isSelected != child.isSelected();
    final int mode = mTouchMode;
    final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLLING
            && mMotionPosition == position;
    final boolean updateChildPressed = isPressed != child.isPressed();
    final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();

    int itemViewType = mAdapter.getItemViewType(position);

    LayoutParams layoutParams;
    if (itemViewType == ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
        layoutParams = generateWrapperLayoutParams(child);
    } else {
        layoutParams = generateChildLayoutParams(child);
    }

    layoutParams.viewType = itemViewType;
    layoutParams.position = position;

    if (recycled || (layoutParams.recycledHeaderFooter
            && layoutParams.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
        if (DBG)
            Log.d(TAG, "setupChild attachViewToParent position:" + position);
        attachViewToParent(child, flowDown ? -1 : 0, layoutParams);
    } else {
        if (DBG)
            Log.d(TAG, "setupChild addViewInLayout position:" + position);
        if (layoutParams.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
            layoutParams.recycledHeaderFooter = true;
        }
        addViewInLayout(child, flowDown ? -1 : 0, layoutParams, true);
    }

    if (updateChildSelected) {
        child.setSelected(isSelected);
    }

    if (updateChildPressed) {
        child.setPressed(isPressed);
    }

    if (needToMeasure) {
        if (DBG)
            Log.d(TAG, "setupChild onMeasureChild position:" + position);
        onMeasureChild(child, layoutParams);
    } else {
        if (DBG)
            Log.d(TAG, "setupChild cleanupLayoutState position:" + position);
        cleanupLayoutState(child);
    }

    final int w = child.getMeasuredWidth();
    final int h = child.getMeasuredHeight();
    final int childTop = flowDown ? y : y - h;

    if (DBG) {
        Log.d(TAG, "setupChild position:" + position + " h:" + h + " w:" + w);
    }

    final int childrenLeft = getChildLeft(position);

    if (needToMeasure) {
        final int childRight = childrenLeft + w;
        final int childBottom = childTop + h;
        onLayoutChild(child, position, flowDown, childrenLeft, childTop, childRight, childBottom);
    } else {
        onOffsetChild(child, position, flowDown, childrenLeft, childTop);
    }

}

From source file:com.cxsplay.wallyskim.widget.flexbox.FlexboxLayout.java

/**
 * Shrink the flex items along the main axis based on the individual flexShrink attribute.
 *
 * @param widthMeasureSpec     the horizontal space requirements as imposed by the parent
 * @param heightMeasureSpec    the vertical space requirements as imposed by the parent
 * @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   w w w .  j  a v  a2 s  .  c  o  m*/
 *                             be an absolute index in the flex container (FlexboxLayout),
 *                             not the relative index in the flex line.
 * @param calledRecursively    true if this method is called recursively, false otherwise
 * @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(int widthMeasureSpec, int heightMeasureSpec, FlexLine flexLine,
        @FlexDirection int flexDirection, int maxMainSize, int paddingAlongMainAxis, int startIndex,
        boolean calledRecursively) {
    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;

    // Setting the cross size of the flex line as the temporal value since the cross size of
    // each flex item may be changed from the initial calculation
    // (in the measureHorizontal/measureVertical method) even this method is part of the main
    // size determination.
    // E.g. If a TextView's layout_width is set to 0dp, layout_height is set to wrap_content,
    // and layout_flexGrow is set to 1, the TextView is trying to expand to the vertical
    // direction to enclose its content (in the measureHorizontal method), but
    // the width will be expanded in this method. In that case, the height needs to be measured
    // again with the expanded width.
    int largestCrossSize = 0;
    if (!calledRecursively) {
        flexLine.mCrossSize = Integer.MIN_VALUE;
    }
    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;
                    }
                }
                int childHeightMeasureSpec = getChildHeightMeasureSpec(heightMeasureSpec, lp);
                child.measure(MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY),
                        childHeightMeasureSpec);
                largestCrossSize = Math.max(largestCrossSize,
                        child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
            }
            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;
                    }
                }
                int childWidthMeasureSpec = getChildWidthMeasureSpec(widthMeasureSpec, lp);
                child.measure(childWidthMeasureSpec,
                        MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY));
                largestCrossSize = Math.max(largestCrossSize,
                        child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
            }
            flexLine.mMainSize += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
        }
        flexLine.mCrossSize = Math.max(flexLine.mCrossSize, largestCrossSize);
        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(widthMeasureSpec, heightMeasureSpec, flexLine, flexDirection, maxMainSize,
                paddingAlongMainAxis, startIndex, true);
    }
    return childIndex;
}

From source file:com.cxsplay.wallyskim.widget.flexbox.FlexboxLayout.java

/**
 * Expand the flex items along the main axis based on the individual flexGrow attribute.
 *
 * @param widthMeasureSpec     the horizontal space requirements as imposed by the parent
 * @param heightMeasureSpec    the vertical space requirements as imposed by the parent
 * @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// w  w  w  . ja v  a2 s .c  om
 *                             be an absolute index in the flex container (FlexboxLayout),
 *                             not the relative index in the flex line.
 * @param calledRecursively    true if this method is called recursively, false otherwise
 * @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(int widthMeasureSpec, int heightMeasureSpec, FlexLine flexLine,
        @FlexDirection int flexDirection, int maxMainSize, int paddingAlongMainAxis, int startIndex,
        boolean calledRecursively) {
    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;

    // Setting the cross size of the flex line as the temporal value since the cross size of
    // each flex item may be changed from the initial calculation
    // (in the measureHorizontal/measureVertical method) even this method is part of the main
    // size determination.
    // E.g. If a TextView's layout_width is set to 0dp, layout_height is set to wrap_content,
    // and layout_flexGrow is set to 1, the TextView is trying to expand to the vertical
    // direction to enclose its content (in the measureHorizontal method), but
    // the width will be expanded in this method. In that case, the height needs to be measured
    // again with the expanded width.
    if (!calledRecursively) {
        flexLine.mCrossSize = Integer.MIN_VALUE;
    }
    int largestCrossSize = 0;
    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;
                    }
                }
                int childHeightMeasureSpec = getChildHeightMeasureSpec(heightMeasureSpec, lp);
                child.measure(MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY),
                        childHeightMeasureSpec);
                largestCrossSize = Math.max(largestCrossSize,
                        child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
            }
            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;
                    }
                }
                int childWidthMeasureSpec = getChildWidthMeasureSpec(widthMeasureSpec, lp);
                child.measure(childWidthMeasureSpec,
                        MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY));
                largestCrossSize = Math.max(largestCrossSize,
                        child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
            }
            flexLine.mMainSize += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
        }
        flexLine.mCrossSize = Math.max(flexLine.mCrossSize, largestCrossSize);
        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(widthMeasureSpec, heightMeasureSpec, flexLine, flexDirection, maxMainSize,
                paddingAlongMainAxis, startIndex, true);
    }
    return childIndex;
}

From source file:com.example.mvpdemo.widget.NarrowParentViewPager.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.

    Log.i("xx", "================ onMeasure ================");
    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 . j av  a  2 s. 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 && (child == mCurrent && mDragDistance == 0 || child != mCurrent)) {
            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 - 2 * (OFFSET + PADDING)), MeasureSpec.EXACTLY);
                child.measure(widthSpec, mChildHeightMeasureSpec);
            }
        }
    }
}

From source file:com.example.GoIceland.grids.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 va2s  .  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;

    int failed = 0;
    while (nextCol >= 0 && mItemBottoms[nextCol] < fillTo && position < mItemCount && failed < 5) {

        final View child = obtainView(position, null);

        if (child == null) {
            failed++;
            continue;
        }
        failed = 0;

        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;
            nextCol = 0;
        } 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;

        /**
         * Magic does not exist
         */
        //            child.measure(MeasureSpec.EXACTLY, MeasureSpec.UNSPECIFIED);

        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];

            //                final int colEnd = Math.min(mColCount, nextCol + lp.span);
            // Only for span = maxCol
            for (int i = 0; i < mColCount; 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;
        if (span > 1) {
            childLeft = paddingLeft;
        } else {
            childLeft = paddingLeft + nextCol * (colWidth + itemMargin);
        }
        final int childRight = childLeft + child.getMeasuredWidth();
        child.layout(childLeft, childTop, childRight, childBottom);

        rec.left = childLeft;
        rec.top = childTop;
        rec.right = childRight;
        rec.bottom = childBottom;
        rec.hasRecRecord = true;

        // 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);
        }

        final int colEnd = Math.min(mColCount, nextCol + lp.span);
        for (int i = nextCol; i < colEnd; 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:com.example.sky.test.view.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  .ja  va  2  s  .  co  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 ViewPager.LayoutParams lp = (ViewPager.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 != ViewPager.LayoutParams.WRAP_CONTENT) {
                    widthMode = MeasureSpec.EXACTLY;
                    if (lp.width != ViewPager.LayoutParams.MATCH_PARENT) {
                        widthSize = lp.width;
                    }
                }
                if (lp.height != ViewPager.LayoutParams.WRAP_CONTENT) {
                    heightMode = MeasureSpec.EXACTLY;
                    if (lp.height != ViewPager.LayoutParams.MATCH_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 ViewPager.LayoutParams lp = (ViewPager.LayoutParams) child.getLayoutParams();
            if (lp == null || !lp.isDecor) {
                final int widthSpec = MeasureSpec.makeMeasureSpec((int) (childWidthSize * lp.widthFactor),
                        MeasureSpec.EXACTLY);
                child.measure(widthSpec, mChildHeightMeasureSpec);
            }
        }
    }
}