Example usage for android.view Gravity VERTICAL_GRAVITY_MASK

List of usage examples for android.view Gravity VERTICAL_GRAVITY_MASK

Introduction

In this page you can find the example usage for android.view Gravity VERTICAL_GRAVITY_MASK.

Prototype

int VERTICAL_GRAVITY_MASK

To view the source code for android.view Gravity VERTICAL_GRAVITY_MASK.

Click Source Link

Document

Binary mask to get the vertical gravity of a gravity.

Usage

From source file:android.support.v7.widget.Toolbar.java

private void ensureCollapseButtonView() {
    if (mCollapseButtonView == null) {
        mCollapseButtonView = new ImageButton(getContext(), null, R.attr.toolbarNavigationButtonStyle);
        mCollapseButtonView.setImageDrawable(mCollapseIcon);
        mCollapseButtonView.setContentDescription(mCollapseDescription);
        final LayoutParams lp = generateDefaultLayoutParams();
        lp.gravity = GravityCompat.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
        lp.mViewType = LayoutParams.EXPANDED;
        mCollapseButtonView.setLayoutParams(lp);
        mCollapseButtonView.setOnClickListener(new OnClickListener() {
            @Override//from  w w  w  . j ava2s . co m
            public void onClick(View v) {
                collapseActionView();
            }
        });
    }
}

From source file:android.support.v7ox.widget.Toolbar.java

private void ensureNavButtonView() {
    if (mNavButtonView == null) {
        mNavButtonView = new ImageButton(getContext(), null, R.attr.toolbarNavigationButtonStyle_ox);
        final LayoutParams lp = generateDefaultLayoutParams();
        lp.gravity = GravityCompat.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
        mNavButtonView.setLayoutParams(lp);
    }//from ww  w  . ja v a 2  s.  co  m
}

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

private void getDesiredAnchoredChildRectWithoutConstraints(View child, int layoutDirection, Rect anchorRect,
        Rect out, LayoutParams lp, int childWidth, int childHeight) {
    final int absGravity = GravityCompat.getAbsoluteGravity(resolveAnchoredChildGravity(lp.gravity),
            layoutDirection);// w w  w .  j av a 2 s .  co m
    final int absAnchorGravity = GravityCompat.getAbsoluteGravity(resolveGravity(lp.anchorGravity),
            layoutDirection);

    final int hgrav = absGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
    final int vgrav = absGravity & Gravity.VERTICAL_GRAVITY_MASK;
    final int anchorHgrav = absAnchorGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
    final int anchorVgrav = absAnchorGravity & Gravity.VERTICAL_GRAVITY_MASK;

    int left;
    int top;

    // Align to the anchor. This puts us in an assumed right/bottom child view gravity.
    // If this is not the case we will subtract out the appropriate portion of
    // the child size below.
    switch (anchorHgrav) {
    default:
    case Gravity.LEFT:
        left = anchorRect.left;
        break;
    case Gravity.RIGHT:
        left = anchorRect.right;
        break;
    case Gravity.CENTER_HORIZONTAL:
        left = anchorRect.left + anchorRect.width() / 2;
        break;
    }

    switch (anchorVgrav) {
    default:
    case Gravity.TOP:
        top = anchorRect.top;
        break;
    case Gravity.BOTTOM:
        top = anchorRect.bottom;
        break;
    case Gravity.CENTER_VERTICAL:
        top = anchorRect.top + anchorRect.height() / 2;
        break;
    }

    // Offset by the child view's gravity itself. The above assumed right/bottom gravity.
    switch (hgrav) {
    default:
    case Gravity.LEFT:
        left -= childWidth;
        break;
    case Gravity.RIGHT:
        // Do nothing, we're already in position.
        break;
    case Gravity.CENTER_HORIZONTAL:
        left -= childWidth / 2;
        break;
    }

    switch (vgrav) {
    default:
    case Gravity.TOP:
        top -= childHeight;
        break;
    case Gravity.BOTTOM:
        // Do nothing, we're already in position.
        break;
    case Gravity.CENTER_VERTICAL:
        top -= childHeight / 2;
        break;
    }

    out.set(left, top, left + childWidth, top + childHeight);
}

From source file:android.support.v7ox.widget.Toolbar.java

private void ensureCollapseButtonView() {
    if (mCollapseButtonView == null) {
        mCollapseButtonView = new ImageButton(getContext(), null, R.attr.toolbarNavigationButtonStyle_ox);
        mCollapseButtonView.setImageDrawable(mCollapseIcon);
        mCollapseButtonView.setContentDescription(mCollapseDescription);
        final LayoutParams lp = generateDefaultLayoutParams();
        lp.gravity = GravityCompat.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
        lp.mViewType = LayoutParams.EXPANDED;
        mCollapseButtonView.setLayoutParams(lp);
        mCollapseButtonView.setOnClickListener(new OnClickListener() {
            @Override//  w  w  w .ja  v  a2s . co  m
            public void onClick(View v) {
                collapseActionView();
            }
        });
    }
}

From source file:com.android.incallui.widget.multiwaveview.GlowPadView.java

private void computeInsets(int dx, int dy) {
    final int layoutDirection = getLayoutDirection();
    final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);

    switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
    case Gravity.LEFT:
        mHorizontalInset = 0;/* ww  w.ja v a 2s .com*/
        break;
    case Gravity.RIGHT:
        mHorizontalInset = dx;
        break;
    case Gravity.CENTER_HORIZONTAL:
    default:
        mHorizontalInset = dx / 2;
        break;
    }
    switch (absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK) {
    case Gravity.TOP:
        mVerticalInset = 0;
        break;
    case Gravity.BOTTOM:
        mVerticalInset = dy;
        break;
    case Gravity.CENTER_VERTICAL:
    default:
        mVerticalInset = dy / 2;
        break;
    }
}

From source file:com.jecelyin.editor.v2.widget.AnyDrawerLayout.java

/**
 * @param gravity the gravity of the child to return. If specified as a
 *            relative value, it will be resolved according to the current
 *            layout direction./*from ww w. j  a  v  a2 s.c o  m*/
 * @return the drawer with the specified gravity
 */
View findDrawerWithGravity(int gravity) {
    final int absHorizGravity = GravityCompat.getAbsoluteGravity(gravity, ViewCompat.getLayoutDirection(this))
            & Gravity.HORIZONTAL_GRAVITY_MASK;
    final int absVerticalGravity = GravityCompat.getAbsoluteGravity(gravity,
            ViewCompat.getLayoutDirection(this)) & Gravity.VERTICAL_GRAVITY_MASK;
    final int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = getChildAt(i);
        final int childAbsGravity = getDrawerViewAbsoluteGravity(child);
        if ((absHorizGravity != 0 && (childAbsGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == absHorizGravity)
                || (absVerticalGravity != 0
                        && (childAbsGravity & Gravity.VERTICAL_GRAVITY_MASK) == absVerticalGravity)

        ) {
            return child;
        }
    }
    return null;
}

From source file:com.android.incallui.widget.multiwaveview.GlowPadView.java

/**
 * Given the desired width and height of the ring and the allocated width and height, compute
 * how much we need to scale the ring./*from   w w  w.java  2s  .  c o m*/
 */
private float computeScaleFactor(int desiredWidth, int desiredHeight, int actualWidth, int actualHeight) {

    // Return unity if scaling is not allowed.
    if (!mAllowScaling)
        return 1f;

    final int layoutDirection = getLayoutDirection();
    final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);

    float scaleX = 1f;
    float scaleY = 1f;

    // We use the gravity as a cue for whether we want to scale on a particular axis.
    // We only scale to fit horizontally if we're not pinned to the left or right. Likewise,
    // we only scale to fit vertically if we're not pinned to the top or bottom. In these
    // cases, we want the ring to hang off the side or top/bottom, respectively.
    switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
    case Gravity.LEFT:
    case Gravity.RIGHT:
        break;
    case Gravity.CENTER_HORIZONTAL:
    default:
        if (desiredWidth > actualWidth) {
            scaleX = (1f * actualWidth - mMaxTargetWidth) / (desiredWidth - mMaxTargetWidth);
        }
        break;
    }
    switch (absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK) {
    case Gravity.TOP:
    case Gravity.BOTTOM:
        break;
    case Gravity.CENTER_VERTICAL:
    default:
        if (desiredHeight > actualHeight) {
            scaleY = (1f * actualHeight - mMaxTargetHeight) / (desiredHeight - mMaxTargetHeight);
        }
        break;
    }
    return Math.min(scaleX, scaleY);
}

From source file:com.tylz.jiaoyanglogistics.view.LazyViewPager.java

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    mInLayout = true;//from  w  w w .ja  v a2s . c  o m
    populate();
    mInLayout = false;

    final int count = getChildCount();
    int width = r - l;
    int height = b - t;
    int paddingLeft = getPaddingLeft();
    int paddingTop = getPaddingTop();
    int paddingRight = getPaddingRight();
    int paddingBottom = getPaddingBottom();
    final int scrollX = getScrollX();

    int decorCount = 0;

    for (int i = 0; i < count; i++) {
        final View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            ItemInfo ii;
            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;
                }
                switch (vgrav) {
                default:
                    childTop = paddingTop;
                    break;
                case Gravity.TOP:
                    childTop = paddingTop;
                    paddingTop += child.getMeasuredHeight();
                    break;
                case Gravity.CENTER_VERTICAL:
                    childTop = Math.max((height - child.getMeasuredHeight()) / 2, paddingTop);
                    break;
                case Gravity.BOTTOM:
                    childTop = height - paddingBottom - child.getMeasuredHeight();
                    paddingBottom += child.getMeasuredHeight();
                    break;
                }
                childLeft += scrollX;
                decorCount++;
                child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(),
                        childTop + child.getMeasuredHeight());
            } else if ((ii = infoForChild(child)) != null) {
                int loff = (width + mPageMargin) * ii.position;
                childLeft = paddingLeft + loff;
                childTop = paddingTop;
                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());
            }
        }
    }
    mTopPageBounds = paddingTop;
    mBottomPageBounds = height - paddingBottom;
    mDecorChildCount = decorCount;
    mFirstLayout = false;
}

From source file:com.chenglong.muscle.ui.LazyViewPager.java

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    mInLayout = true;/*from  w w  w  . ja va 2  s.c  om*/
    populate();
    mInLayout = false;
    final int count = getChildCount();
    int width = r - l;
    int height = b - t;
    int paddingLeft = getPaddingLeft();
    int paddingTop = getPaddingTop();
    int paddingRight = getPaddingRight();
    int paddingBottom = getPaddingBottom();
    final int scrollX = getScrollX();
    int decorCount = 0;
    for (int i = 0; i < count; i++) {
        final View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            ItemInfo ii;
            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;
                }
                switch (vgrav) {
                default:
                    childTop = paddingTop;
                    break;
                case Gravity.TOP:
                    childTop = paddingTop;
                    paddingTop += child.getMeasuredHeight();
                    break;
                case Gravity.CENTER_VERTICAL:
                    childTop = Math.max((height - child.getMeasuredHeight()) / 2, paddingTop);
                    break;
                case Gravity.BOTTOM:
                    childTop = height - paddingBottom - child.getMeasuredHeight();
                    paddingBottom += child.getMeasuredHeight();
                    break;
                }
                childLeft += scrollX;
                decorCount++;
                child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(),
                        childTop + child.getMeasuredHeight());
            } else if ((ii = infoForChild(child)) != null) {
                int loff = (width + mPageMargin) * ii.position;
                childLeft = paddingLeft + loff;
                childTop = paddingTop;
                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());
            }
        }
    }
    mTopPageBounds = paddingTop;
    mBottomPageBounds = height - paddingBottom;
    mDecorChildCount = decorCount;
    mFirstLayout = false;
}

From source file:android.support.v7.widget.LinearLayoutCompat.java

/**
 * Measures the children when the orientation of this LinearLayout is set
 * to {@link #HORIZONTAL}.//from w  w w  . j a v  a2s. c  o  m
 *
 * @param widthMeasureSpec Horizontal space requirements as imposed by the parent.
 * @param heightMeasureSpec Vertical space requirements as imposed by the parent.
 *
 * @see #getOrientation()
 * @see #setOrientation(int)
 * @see #onMeasure(int, int)
 */
void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) {
    mTotalLength = 0;
    int maxHeight = 0;
    int childState = 0;
    int alternativeMaxHeight = 0;
    int weightedMaxHeight = 0;
    boolean allFillParent = true;
    float totalWeight = 0;

    final int count = getVirtualChildCount();

    final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    boolean matchHeight = false;
    boolean skippedMeasure = false;

    if (mMaxAscent == null || mMaxDescent == null) {
        mMaxAscent = new int[VERTICAL_GRAVITY_COUNT];
        mMaxDescent = new int[VERTICAL_GRAVITY_COUNT];
    }

    final int[] maxAscent = mMaxAscent;
    final int[] maxDescent = mMaxDescent;

    maxAscent[0] = maxAscent[1] = maxAscent[2] = maxAscent[3] = -1;
    maxDescent[0] = maxDescent[1] = maxDescent[2] = maxDescent[3] = -1;

    final boolean baselineAligned = mBaselineAligned;
    final boolean useLargestChild = mUseLargestChild;

    final boolean isExactly = widthMode == MeasureSpec.EXACTLY;

    int largestChildWidth = Integer.MIN_VALUE;

    // See how wide everyone is. Also remember max height.
    for (int i = 0; i < count; ++i) {
        final View child = getVirtualChildAt(i);

        if (child == null) {
            mTotalLength += measureNullChild(i);
            continue;
        }

        if (child.getVisibility() == GONE) {
            i += getChildrenSkipCount(child, i);
            continue;
        }

        if (hasDividerBeforeChildAt(i)) {
            mTotalLength += mDividerWidth;
        }

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

        totalWeight += lp.weight;

        if (widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0) {
            // Optimization: don't bother measuring children who are going to use
            // leftover space. These views will get measured again down below if
            // there is any leftover space.
            if (isExactly) {
                mTotalLength += lp.leftMargin + lp.rightMargin;
            } else {
                final int totalLength = mTotalLength;
                mTotalLength = Math.max(totalLength, totalLength + lp.leftMargin + lp.rightMargin);
            }

            // Baseline alignment requires to measure widgets to obtain the
            // baseline offset (in particular for TextViews). The following
            // defeats the optimization mentioned above. Allow the child to
            // use as much space as it wants because we can shrink things
            // later (and re-measure).
            if (baselineAligned) {
                final int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                child.measure(freeSpec, freeSpec);
            } else {
                skippedMeasure = true;
            }
        } else {
            int oldWidth = Integer.MIN_VALUE;

            if (lp.width == 0 && lp.weight > 0) {
                // widthMode is either UNSPECIFIED or AT_MOST, and this
                // child
                // wanted to stretch to fill available space. Translate that to
                // WRAP_CONTENT so that it does not end up with a width of 0
                oldWidth = 0;
                lp.width = LayoutParams.WRAP_CONTENT;
            }

            // Determine how big this child would like to be. If this or
            // previous children have given a weight, then we allow it to
            // use all available space (and we will shrink things later
            // if needed).
            measureChildBeforeLayout(child, i, widthMeasureSpec, totalWeight == 0 ? mTotalLength : 0,
                    heightMeasureSpec, 0);

            if (oldWidth != Integer.MIN_VALUE) {
                lp.width = oldWidth;
            }

            final int childWidth = child.getMeasuredWidth();
            if (isExactly) {
                mTotalLength += childWidth + lp.leftMargin + lp.rightMargin + getNextLocationOffset(child);
            } else {
                final int totalLength = mTotalLength;
                mTotalLength = Math.max(totalLength, totalLength + childWidth + lp.leftMargin + lp.rightMargin
                        + getNextLocationOffset(child));
            }

            if (useLargestChild) {
                largestChildWidth = Math.max(childWidth, largestChildWidth);
            }
        }

        boolean matchHeightLocally = false;
        if (heightMode != MeasureSpec.EXACTLY && lp.height == LayoutParams.MATCH_PARENT) {
            // The height of the linear layout will scale, and at least one
            // child said it wanted to match our height. Set a flag indicating that
            // we need to remeasure at least that view when we know our height.
            matchHeight = true;
            matchHeightLocally = true;
        }

        final int margin = lp.topMargin + lp.bottomMargin;
        final int childHeight = child.getMeasuredHeight() + margin;
        childState = ViewUtils.combineMeasuredStates(childState, ViewCompat.getMeasuredState(child));

        if (baselineAligned) {
            final int childBaseline = child.getBaseline();
            if (childBaseline != -1) {
                // Translates the child's vertical gravity into an index
                // in the range 0..VERTICAL_GRAVITY_COUNT
                final int gravity = (lp.gravity < 0 ? mGravity : lp.gravity) & Gravity.VERTICAL_GRAVITY_MASK;
                final int index = ((gravity >> Gravity.AXIS_Y_SHIFT) & ~Gravity.AXIS_SPECIFIED) >> 1;

                maxAscent[index] = Math.max(maxAscent[index], childBaseline);
                maxDescent[index] = Math.max(maxDescent[index], childHeight - childBaseline);
            }
        }

        maxHeight = Math.max(maxHeight, childHeight);

        allFillParent = allFillParent && lp.height == LayoutParams.MATCH_PARENT;
        if (lp.weight > 0) {
            /*
             * Heights of weighted Views are bogus if we end up
             * remeasuring, so keep them separate.
             */
            weightedMaxHeight = Math.max(weightedMaxHeight, matchHeightLocally ? margin : childHeight);
        } else {
            alternativeMaxHeight = Math.max(alternativeMaxHeight, matchHeightLocally ? margin : childHeight);
        }

        i += getChildrenSkipCount(child, i);
    }

    if (mTotalLength > 0 && hasDividerBeforeChildAt(count)) {
        mTotalLength += mDividerWidth;
    }

    // Check mMaxAscent[INDEX_TOP] first because it maps to Gravity.TOP,
    // the most common case
    if (maxAscent[INDEX_TOP] != -1 || maxAscent[INDEX_CENTER_VERTICAL] != -1 || maxAscent[INDEX_BOTTOM] != -1
            || maxAscent[INDEX_FILL] != -1) {
        final int ascent = Math.max(maxAscent[INDEX_FILL], Math.max(maxAscent[INDEX_CENTER_VERTICAL],
                Math.max(maxAscent[INDEX_TOP], maxAscent[INDEX_BOTTOM])));
        final int descent = Math.max(maxDescent[INDEX_FILL], Math.max(maxDescent[INDEX_CENTER_VERTICAL],
                Math.max(maxDescent[INDEX_TOP], maxDescent[INDEX_BOTTOM])));
        maxHeight = Math.max(maxHeight, ascent + descent);
    }

    if (useLargestChild && (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED)) {
        mTotalLength = 0;

        for (int i = 0; i < count; ++i) {
            final View child = getVirtualChildAt(i);

            if (child == null) {
                mTotalLength += measureNullChild(i);
                continue;
            }

            if (child.getVisibility() == GONE) {
                i += getChildrenSkipCount(child, i);
                continue;
            }

            final LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) child
                    .getLayoutParams();
            if (isExactly) {
                mTotalLength += largestChildWidth + lp.leftMargin + lp.rightMargin
                        + getNextLocationOffset(child);
            } else {
                final int totalLength = mTotalLength;
                mTotalLength = Math.max(totalLength, totalLength + largestChildWidth + lp.leftMargin
                        + lp.rightMargin + getNextLocationOffset(child));
            }
        }
    }

    // Add in our padding
    mTotalLength += getPaddingLeft() + getPaddingRight();

    int widthSize = mTotalLength;

    // Check against our minimum width
    widthSize = Math.max(widthSize, getSuggestedMinimumWidth());

    // Reconcile our calculated size with the widthMeasureSpec
    int widthSizeAndState = ViewCompat.resolveSizeAndState(widthSize, widthMeasureSpec, 0);
    widthSize = widthSizeAndState & ViewCompat.MEASURED_SIZE_MASK;

    // Either expand children with weight to take up available space or
    // shrink them if they extend beyond our current bounds. If we skipped
    // measurement on any children, we need to measure them now.
    int delta = widthSize - mTotalLength;
    if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
        float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;

        maxAscent[0] = maxAscent[1] = maxAscent[2] = maxAscent[3] = -1;
        maxDescent[0] = maxDescent[1] = maxDescent[2] = maxDescent[3] = -1;
        maxHeight = -1;

        mTotalLength = 0;

        for (int i = 0; i < count; ++i) {
            final View child = getVirtualChildAt(i);

            if (child == null || child.getVisibility() == View.GONE) {
                continue;
            }

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

            float childExtra = lp.weight;
            if (childExtra > 0) {
                // Child said it could absorb extra space -- give him his share
                int share = (int) (childExtra * delta / weightSum);
                weightSum -= childExtra;
                delta -= share;

                final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
                        getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin, lp.height);

                // TODO: Use a field like lp.isMeasured to figure out if this
                // child has been previously measured
                if ((lp.width != 0) || (widthMode != MeasureSpec.EXACTLY)) {
                    // child was measured once already above ... base new measurement
                    // on stored values
                    int childWidth = child.getMeasuredWidth() + share;
                    if (childWidth < 0) {
                        childWidth = 0;
                    }

                    child.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
                            childHeightMeasureSpec);
                } else {
                    // child was skipped in the loop above. Measure for this first time here
                    child.measure(MeasureSpec.makeMeasureSpec(share > 0 ? share : 0, MeasureSpec.EXACTLY),
                            childHeightMeasureSpec);
                }

                // Child may now not fit in horizontal dimension.
                childState = ViewUtils.combineMeasuredStates(childState,
                        ViewCompat.getMeasuredState(child) & ViewCompat.MEASURED_STATE_MASK);
            }

            if (isExactly) {
                mTotalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin
                        + getNextLocationOffset(child);
            } else {
                final int totalLength = mTotalLength;
                mTotalLength = Math.max(totalLength, totalLength + child.getMeasuredWidth() + lp.leftMargin
                        + lp.rightMargin + getNextLocationOffset(child));
            }

            boolean matchHeightLocally = heightMode != MeasureSpec.EXACTLY
                    && lp.height == LayoutParams.MATCH_PARENT;

            final int margin = lp.topMargin + lp.bottomMargin;
            int childHeight = child.getMeasuredHeight() + margin;
            maxHeight = Math.max(maxHeight, childHeight);
            alternativeMaxHeight = Math.max(alternativeMaxHeight, matchHeightLocally ? margin : childHeight);

            allFillParent = allFillParent && lp.height == LayoutParams.MATCH_PARENT;

            if (baselineAligned) {
                final int childBaseline = child.getBaseline();
                if (childBaseline != -1) {
                    // Translates the child's vertical gravity into an index in the range 0..2
                    final int gravity = (lp.gravity < 0 ? mGravity : lp.gravity)
                            & Gravity.VERTICAL_GRAVITY_MASK;
                    final int index = ((gravity >> Gravity.AXIS_Y_SHIFT) & ~Gravity.AXIS_SPECIFIED) >> 1;

                    maxAscent[index] = Math.max(maxAscent[index], childBaseline);
                    maxDescent[index] = Math.max(maxDescent[index], childHeight - childBaseline);
                }
            }
        }

        // Add in our padding
        mTotalLength += getPaddingLeft() + getPaddingRight();
        // TODO: Should we update widthSize with the new total length?

        // Check mMaxAscent[INDEX_TOP] first because it maps to Gravity.TOP,
        // the most common case
        if (maxAscent[INDEX_TOP] != -1 || maxAscent[INDEX_CENTER_VERTICAL] != -1
                || maxAscent[INDEX_BOTTOM] != -1 || maxAscent[INDEX_FILL] != -1) {
            final int ascent = Math.max(maxAscent[INDEX_FILL], Math.max(maxAscent[INDEX_CENTER_VERTICAL],
                    Math.max(maxAscent[INDEX_TOP], maxAscent[INDEX_BOTTOM])));
            final int descent = Math.max(maxDescent[INDEX_FILL], Math.max(maxDescent[INDEX_CENTER_VERTICAL],
                    Math.max(maxDescent[INDEX_TOP], maxDescent[INDEX_BOTTOM])));
            maxHeight = Math.max(maxHeight, ascent + descent);
        }
    } else {
        alternativeMaxHeight = Math.max(alternativeMaxHeight, weightedMaxHeight);

        // We have no limit, so make all weighted views as wide as the largest child.
        // Children will have already been measured once.
        if (useLargestChild && widthMode != MeasureSpec.EXACTLY) {
            for (int i = 0; i < count; i++) {
                final View child = getVirtualChildAt(i);

                if (child == null || child.getVisibility() == View.GONE) {
                    continue;
                }

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

                float childExtra = lp.weight;
                if (childExtra > 0) {
                    child.measure(MeasureSpec.makeMeasureSpec(largestChildWidth, MeasureSpec.EXACTLY),
                            MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), MeasureSpec.EXACTLY));
                }
            }
        }
    }

    if (!allFillParent && heightMode != MeasureSpec.EXACTLY) {
        maxHeight = alternativeMaxHeight;
    }

    maxHeight += getPaddingTop() + getPaddingBottom();

    // Check against our minimum height
    maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());

    setMeasuredDimension(widthSizeAndState | (childState & ViewCompat.MEASURED_STATE_MASK),
            ViewCompat.resolveSizeAndState(maxHeight, heightMeasureSpec,
                    (childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT)));

    if (matchHeight) {
        forceUniformHeight(count, widthMeasureSpec);
    }
}