Example usage for android.view View measure

List of usage examples for android.view View measure

Introduction

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

Prototype

public final void measure(int widthMeasureSpec, int heightMeasureSpec) 

Source Link

Document

This is called to find out how big a view should be.

Usage

From source file:administrator.example.com.myscrollview.VerticalViewPager.java

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // For simple implementation, or 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));

    // Children are just made to fill our space.
    int childWidthSize = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
    int childHeightSize = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();

    /*/* www  .j av 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;
                Log.d(TAG, "gravity: " + lp.gravity + " hgrav: " + hgrav + " vgrav: " + vgrav);
                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;
                } /* end of if */

                final int widthSpec = MeasureSpec.makeMeasureSpec(childWidthSize, widthMode);
                final int heightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, heightMode);
                child.measure(widthSpec, heightSpec);

                if (consumeVertical) {
                    childHeightSize -= child.getMeasuredHeight();
                } else if (consumeHorizontal) {
                    childWidthSize -= child.getMeasuredWidth();
                } /* end of if */
            } /* end of if */
        } /* end of if */
    } /* end of for */

    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) {
                child.measure(mChildWidthMeasureSpec, mChildHeightMeasureSpec);
            } /* end of if */
        } /* end of if */
    } /* end of for */
}

From source file:cn.ismartv.tvrecyclerview.widget.StaggeredGridLayoutManager.java

private void measureChildWithDecorationsAndMargin(View child, int widthSpec, int heightSpec,
        boolean alreadyMeasured) {
    calculateItemDecorationsForChild(child, mTmpRect);
    LayoutParams lp = (LayoutParams) child.getLayoutParams();
    widthSpec = updateSpecWithExtra(widthSpec, lp.leftMargin + mTmpRect.left, lp.rightMargin + mTmpRect.right);
    heightSpec = updateSpecWithExtra(heightSpec, lp.topMargin + mTmpRect.top,
            lp.bottomMargin + mTmpRect.bottom);
    final boolean measure = alreadyMeasured ? shouldReMeasureChild(child, widthSpec, heightSpec, lp)
            : shouldMeasureChild(child, widthSpec, heightSpec, lp);
    if (measure) {
        child.measure(widthSpec, heightSpec);
    }//from   w  ww  .  j a  v  a2s  .  co m

}

From source file:cn.bingoogolapple.swipebacklayout.BGASwipeBackLayout.java

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    if (widthMode != MeasureSpec.EXACTLY) {
        if (isInEditMode()) {
            // Don't crash the layout editor. Consume all of the space if specified
            // or pick a magic number from thin air otherwise.
            // TODO Better communication with tools of this bogus state.
            // It will crash on a real device.
            if (widthMode == MeasureSpec.AT_MOST) {
                widthMode = MeasureSpec.EXACTLY;
            } else if (widthMode == MeasureSpec.UNSPECIFIED) {
                widthMode = MeasureSpec.EXACTLY;
                widthSize = 300;// ww  w  . j  a va 2  s .co m
            }
        } else {
            throw new IllegalStateException("Width must have an exact value or MATCH_PARENT");
        }
    } else if (heightMode == MeasureSpec.UNSPECIFIED) {
        if (isInEditMode()) {
            // Don't crash the layout editor. Pick a magic number from thin air instead.
            // TODO Better communication with tools of this bogus state.
            // It will crash on a real device.
            if (heightMode == MeasureSpec.UNSPECIFIED) {
                heightMode = MeasureSpec.AT_MOST;
                heightSize = 300;
            }
        } else {
            throw new IllegalStateException("Height must not be UNSPECIFIED");
        }
    }

    int layoutHeight = 0;
    int maxLayoutHeight = -1;
    switch (heightMode) {
    case MeasureSpec.EXACTLY:
        layoutHeight = maxLayoutHeight = heightSize - getPaddingTop() - getPaddingBottom();
        break;
    case MeasureSpec.AT_MOST:
        maxLayoutHeight = heightSize - getPaddingTop() - getPaddingBottom();
        break;
    }

    // ========================  START ========================
    maxLayoutHeight -= UIUtil.getNavigationBarHeight(mActivity);
    // ========================  END ========================

    float weightSum = 0;
    boolean canSlide = false;
    final int widthAvailable = widthSize - getPaddingLeft() - getPaddingRight();
    int widthRemaining = widthAvailable;
    final int childCount = getChildCount();

    if (childCount > 2) {
        Log.e(TAG, "onMeasure: More than two child views are not supported.");
    }

    // We'll find the current one below.
    mSlideableView = null;

    // First pass. Measure based on child LayoutParams width/height.
    // Weight will incur a second pass.
    for (int i = 0; i < childCount; i++) {
        final View child = getChildAt(i);
        final LayoutParams lp = (LayoutParams) child.getLayoutParams();

        if (child.getVisibility() == GONE) {
            lp.dimWhenOffset = false;
            continue;
        }

        if (lp.weight > 0) {
            weightSum += lp.weight;

            // If we have no width, weight is the only contributor to the final size.
            // Measure this view on the weight pass only.
            if (lp.width == 0)
                continue;
        }

        int childWidthSpec;
        final int horizontalMargin = lp.leftMargin + lp.rightMargin;
        if (lp.width == LayoutParams.WRAP_CONTENT) {
            childWidthSpec = MeasureSpec.makeMeasureSpec(widthAvailable - horizontalMargin,
                    MeasureSpec.AT_MOST);
        } else if (lp.width == LayoutParams.MATCH_PARENT) {
            childWidthSpec = MeasureSpec.makeMeasureSpec(widthAvailable - horizontalMargin,
                    MeasureSpec.EXACTLY);
        } else {
            childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
        }

        int childHeightSpec;
        if (lp.height == LayoutParams.WRAP_CONTENT) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.AT_MOST);
        } else if (lp.height == LayoutParams.MATCH_PARENT) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
        }

        child.measure(childWidthSpec, childHeightSpec);
        final int childWidth = child.getMeasuredWidth();
        final int childHeight = child.getMeasuredHeight();

        if (heightMode == MeasureSpec.AT_MOST && childHeight > layoutHeight) {
            layoutHeight = Math.min(childHeight, maxLayoutHeight);
        }

        widthRemaining -= childWidth;
        canSlide |= lp.slideable = widthRemaining < 0;
        if (lp.slideable) {
            mSlideableView = child;
        }
    }

    // Resolve weight and make sure non-sliding panels are smaller than the full screen.
    if (canSlide || weightSum > 0) {
        final int fixedPanelWidthLimit = widthAvailable - mOverhangSize;

        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);

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

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

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

            final boolean skippedFirstPass = lp.width == 0 && lp.weight > 0;
            final int measuredWidth = skippedFirstPass ? 0 : child.getMeasuredWidth();
            if (canSlide && child != mSlideableView) {
                if (lp.width < 0 && (measuredWidth > fixedPanelWidthLimit || lp.weight > 0)) {
                    // Fixed panels in a sliding configuration should
                    // be clamped to the fixed panel limit.
                    final int childHeightSpec;
                    if (skippedFirstPass) {
                        // Do initial height measurement if we skipped measuring this view
                        // the first time around.
                        if (lp.height == LayoutParams.WRAP_CONTENT) {
                            childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.AT_MOST);
                        } else if (lp.height == LayoutParams.MATCH_PARENT) {
                            childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.EXACTLY);
                        } else {
                            childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
                        }
                    } else {
                        childHeightSpec = MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(),
                                MeasureSpec.EXACTLY);
                    }
                    final int childWidthSpec = MeasureSpec.makeMeasureSpec(fixedPanelWidthLimit,
                            MeasureSpec.EXACTLY);
                    child.measure(childWidthSpec, childHeightSpec);
                }
            } else if (lp.weight > 0) {
                int childHeightSpec;
                if (lp.width == 0) {
                    // This was skipped the first time; figure out a real height spec.
                    if (lp.height == LayoutParams.WRAP_CONTENT) {
                        childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.AT_MOST);
                    } else if (lp.height == LayoutParams.MATCH_PARENT) {
                        childHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.EXACTLY);
                    } else {
                        childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
                    }
                } else {
                    childHeightSpec = MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(),
                            MeasureSpec.EXACTLY);
                }

                if (canSlide) {
                    // Consume available space
                    final int horizontalMargin = lp.leftMargin + lp.rightMargin;
                    final int newWidth = widthAvailable - horizontalMargin;
                    final int childWidthSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);
                    if (measuredWidth != newWidth) {
                        child.measure(childWidthSpec, childHeightSpec);
                    }
                } else {
                    // Distribute the extra width proportionally similar to LinearLayout
                    final int widthToDistribute = Math.max(0, widthRemaining);
                    final int addedWidth = (int) (lp.weight * widthToDistribute / weightSum);
                    final int childWidthSpec = MeasureSpec.makeMeasureSpec(measuredWidth + addedWidth,
                            MeasureSpec.EXACTLY);
                    child.measure(childWidthSpec, childHeightSpec);
                }
            }
        }
    }

    final int measuredWidth = widthSize;
    final int measuredHeight = layoutHeight + getPaddingTop() + getPaddingBottom();

    setMeasuredDimension(measuredWidth, measuredHeight);
    mCanSlide = canSlide;

    if (mDragHelper.getViewDragState() != ViewDragHelper.STATE_IDLE && !canSlide) {
        // Cancel scrolling in progress, it's no longer relevant.
        mDragHelper.abort();
    }
}

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

/**
 * <p>Builds the popup window's content and returns the height the popup
 * should have. Returns -1 when the content already exists.</p>
 *
 * @return the content's height or -1 if content already exists
 *///from  w  w  w . ja  va2  s  .co  m
private int buildDropDown() {
    ViewGroup dropDownView;
    int otherHeights = 0;

    if (mDropDownList == null) {
        Context context = mContext;

        /**
         * This Runnable exists for the sole purpose of checking if the view layout has got
         * completed and if so call showDropDown to display the drop down. This is used to show
         * the drop down as soon as possible after user opens up the search dialog, without
         * waiting for the normal UI pipeline to do it's job which is slower than this method.
         */
        mShowDropDownRunnable = new Runnable() {
            public void run() {
                // View layout should be all done before displaying the drop down.
                View view = getAnchorView();
                if (view != null && view.getWindowToken() != null) {
                    show();
                }
            }
        };

        mDropDownList = new DropDownListView(context, !mModal);
        if (mDropDownListHighlight != null) {
            mDropDownList.setSelector(mDropDownListHighlight);
        }
        mDropDownList.setAdapter(mAdapter);
        mDropDownList.setOnItemClickListener(mItemClickListener);
        mDropDownList.setFocusable(true);
        mDropDownList.setFocusableInTouchMode(true);
        mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                if (position != -1) {
                    DropDownListView dropDownList = mDropDownList;

                    if (dropDownList != null) {
                        dropDownList.mListSelectionHidden = false;
                    }
                }
            }

            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        mDropDownList.setOnScrollListener(mScrollListener);

        if (mItemSelectedListener != null) {
            mDropDownList.setOnItemSelectedListener(mItemSelectedListener);
        }

        dropDownView = mDropDownList;

        View hintView = mPromptView;
        if (hintView != null) {
            // if a hint has been specified, we accomodate more space for it and
            // add a text view in the drop down menu, at the bottom of the list
            LinearLayout hintContainer = new LinearLayout(context);
            hintContainer.setOrientation(LinearLayout.VERTICAL);

            LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f);

            switch (mPromptPosition) {
            case POSITION_PROMPT_BELOW:
                hintContainer.addView(dropDownView, hintParams);
                hintContainer.addView(hintView);
                break;

            case POSITION_PROMPT_ABOVE:
                hintContainer.addView(hintView);
                hintContainer.addView(dropDownView, hintParams);
                break;

            default:
                Log.e(TAG, "Invalid hint position " + mPromptPosition);
                break;
            }

            // Measure the hint's height to find how much more vertical
            // space we need to add to the drop down's height.
            final int widthSize;
            final int widthMode;
            if (mDropDownWidth >= 0) {
                widthMode = MeasureSpec.AT_MOST;
                widthSize = mDropDownWidth;
            } else {
                widthMode = MeasureSpec.UNSPECIFIED;
                widthSize = 0;
            }
            final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode);
            final int heightSpec = MeasureSpec.UNSPECIFIED;
            hintView.measure(widthSpec, heightSpec);

            hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams();
            otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin + hintParams.bottomMargin;

            dropDownView = hintContainer;
        }

        mPopup.setContentView(dropDownView);
    } else {
        dropDownView = (ViewGroup) mPopup.getContentView();
        final View view = mPromptView;
        if (view != null) {
            LinearLayout.LayoutParams hintParams = (LinearLayout.LayoutParams) view.getLayoutParams();
            otherHeights = view.getMeasuredHeight() + hintParams.topMargin + hintParams.bottomMargin;
        }
    }

    // getMaxAvailableHeight() subtracts the padding, so we put it back
    // to get the available height for the whole window
    int padding = 0;
    Drawable background = mPopup.getBackground();
    if (background != null) {
        background.getPadding(mTempRect);
        padding = mTempRect.top + mTempRect.bottom;

        // If we don't have an explicit vertical offset, determine one from the window
        // background so that content will line up.
        if (!mDropDownVerticalOffsetSet) {
            mDropDownVerticalOffset = -mTempRect.top;
        }
    } else {
        mTempRect.setEmpty();
    }

    // Max height available on the screen for a popup.
    final boolean ignoreBottomDecorations = mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
    final int maxHeight = getMaxAvailableHeight(getAnchorView(), mDropDownVerticalOffset,
            ignoreBottomDecorations);
    if (mDropDownAlwaysVisible || mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
        return maxHeight + padding;
    }

    final int childWidthSpec;
    switch (mDropDownWidth) {
    case ViewGroup.LayoutParams.WRAP_CONTENT:
        childWidthSpec = MeasureSpec.makeMeasureSpec(
                mContext.getResources().getDisplayMetrics().widthPixels - (mTempRect.left + mTempRect.right),
                MeasureSpec.AT_MOST);
        break;
    case ViewGroup.LayoutParams.MATCH_PARENT:
        childWidthSpec = MeasureSpec.makeMeasureSpec(
                mContext.getResources().getDisplayMetrics().widthPixels - (mTempRect.left + mTempRect.right),
                MeasureSpec.EXACTLY);
        break;
    default:
        childWidthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.EXACTLY);
        break;
    }

    final int listContent = mDropDownList.measureHeightOfChildrenCompat(childWidthSpec, 0,
            DropDownListView.NO_POSITION, maxHeight - otherHeights, -1);
    // add padding only if the list has items in it, that way we don't show
    // the popup if it is not needed
    if (listContent > 0)
        otherHeights += padding;

    return listContent + otherHeights;
}

From source file:com.devabit.takestock.ui.widget.FlexboxLayout.java

/**
 * Sub method for {@link #onMeasure(int, int)} when the main axis direction is vertical
 * (either from top to bottom or bottom to top).
 *
 * @param widthMeasureSpec  horizontal space requirements as imposed by the parent
 * @param heightMeasureSpec vertical space requirements as imposed by the parent
 * @see #onMeasure(int, int)/*  w w  w  .j  ava 2s  .  co  m*/
 * @see #setFlexDirection(int)
 * @see #setFlexWrap(int)
 * @see #setAlignItems(int)
 * @see #setAlignContent(int)
 */
private void measureVertical(int widthMeasureSpec, int heightMeasureSpec) {
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    int childState = 0;

    mFlexLines.clear();

    // Determine how many flex lines are needed in this layout by measuring each child.
    // (Expand or shrink the view depending on the flexGrow and flexShrink attributes in a later
    // loop)
    int childCount = getChildCount();
    int paddingTop = getPaddingTop();
    int paddingBottom = getPaddingBottom();
    int largestWidthInColumn = Integer.MIN_VALUE;
    FlexLine flexLine = new FlexLine();
    flexLine.mainSize = paddingTop + paddingBottom;
    for (int i = 0; i < childCount; i++) {
        View child = getReorderedChildAt(i);
        if (child == null) {
            addFlexLineIfLastFlexItem(i, childCount, flexLine);
            continue;
        } else if (child.getVisibility() == View.GONE) {
            flexLine.itemCount++;
            addFlexLineIfLastFlexItem(i, childCount, flexLine);
            continue;
        }

        FlexboxLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
        if (lp.alignSelf == LayoutParams.ALIGN_SELF_STRETCH) {
            flexLine.indicesAlignSelfStretch.add(i);
        }

        int childHeight = lp.height;
        if (lp.flexBasisPercent != LayoutParams.FLEX_BASIS_PERCENT_DEFAULT
                && heightMode == MeasureSpec.EXACTLY) {
            childHeight = Math.round(heightSize * lp.flexBasisPercent);
            // Use the dimension from the layout_height attribute if the heightMode is not
            // MeasureSpec.EXACTLY even if any fraction value is set to layout_flexBasisPercent.
            // There are likely quite few use cases where assigning any fraction values
            // with heightMode is not MeasureSpec.EXACTLY (e.g. FlexboxLayout's layout_height
            // is set to wrap_content)
        }

        int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
                getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin, lp.width);
        int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
                getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin, childHeight);
        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);

        // Check the size constraint after the first measurement for the child
        // To prevent the child's width/height violate the size constraints imposed by the
        // {@link LayoutParams#minWidth}, {@link LayoutParams#minHeight},
        // {@link LayoutParams#maxWidth} and {@link LayoutParams#maxHeight} attributes.
        // E.g. When the child's layout_height is wrap_content the measured height may be
        // less than the min height after the first measurement.
        checkSizeConstraints(child);

        childState = ViewCompat.combineMeasuredStates(childState, ViewCompat.getMeasuredState(child));
        largestWidthInColumn = Math.max(largestWidthInColumn,
                child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);

        if (isWrapRequired(mFlexWrap, heightMode, heightSize, flexLine.mainSize,
                child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin, lp)) {
            if (flexLine.itemCount > 0) {
                mFlexLines.add(flexLine);
            }

            flexLine = new FlexLine();
            flexLine.itemCount = 1;
            flexLine.mainSize = paddingTop + paddingBottom;
            largestWidthInColumn = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
        } else {
            flexLine.itemCount++;
        }
        flexLine.mainSize += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
        flexLine.totalFlexGrow += lp.flexGrow;
        flexLine.totalFlexShrink += lp.flexShrink;
        // Temporarily set the cross axis length as the largest child width in the column
        // Expand along the cross axis depending on the mAlignContent property if needed
        // later
        flexLine.crossSize = Math.max(flexLine.crossSize, largestWidthInColumn);

        addFlexLineIfLastFlexItem(i, childCount, flexLine);
    }

    determineMainSize(mFlexDirection, widthMeasureSpec, heightMeasureSpec);
    determineCrossSize(mFlexDirection, widthMeasureSpec, heightMeasureSpec,
            getPaddingLeft() + getPaddingRight());
    // Now cross size for each flex line is determined.
    // Expand the views if alignItems (or alignSelf in each child view) is set to stretch
    stretchViews(mFlexDirection, mAlignItems);
    setMeasuredDimensionForFlex(mFlexDirection, widthMeasureSpec, heightMeasureSpec, childState);
}

From source file:com.example.view.VerticalViewPager.java

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // For simple implementation, or 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));

    // Children are just made to fill our space.
    int childWidthSize = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
    int childHeightSize = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();

    /*/*from   w w  w .  ja  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;
                Log.d(TAG, "gravity: " + lp.gravity + " hgrav: " + hgrav + " vgrav: " + vgrav);
                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;
                } /* end of if */

                final int widthSpec = MeasureSpec.makeMeasureSpec(childWidthSize, widthMode);
                final int heightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, heightMode);
                child.measure(widthSpec, heightSpec);

                if (consumeVertical) {
                    childHeightSize -= child.getMeasuredHeight();
                } else if (consumeHorizontal) {
                    childWidthSize -= child.getMeasuredWidth();
                } /* end of if */
            } /* end of if */
        } /* end of if */
    } /* end of for */

    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) {
                child.measure(mChildWidthMeasureSpec, mChildHeightMeasureSpec);
            } /* end of if */
        } /* end of if */
    } /* end of for */
}

From source file:com.google.android.flexbox.FlexboxLayoutManager.java

private int layoutFlexLineMainAxisVertical(FlexLine flexLine, LayoutState layoutState) {
    assert mFlexboxHelper.mMeasureSpecCache != null;

    int paddingTop = getPaddingTop();
    int paddingBottom = getPaddingBottom();
    int parentHeight = getHeight();

    int childLeft = layoutState.mOffset;
    // childRight is used only for the layout is RTL
    int childRight = layoutState.mOffset;
    if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START) {
        childLeft = childLeft - flexLine.mCrossSize;
        childRight = childRight + flexLine.mCrossSize;
    }/*from w w w.j  av  a 2s  . c  o  m*/
    int startPosition = layoutState.mPosition;

    float childTop;

    // Only used when mFromBottomToTop is true
    float childBottom;
    float spaceBetweenItem = 0f;
    switch (mJustifyContent) {
    case JustifyContent.FLEX_START:
        childTop = paddingTop;
        childBottom = parentHeight - paddingBottom;
        break;
    case JustifyContent.FLEX_END:
        childTop = parentHeight - flexLine.mMainSize + paddingBottom;
        childBottom = flexLine.mMainSize - paddingTop;
        break;
    case JustifyContent.CENTER:
        childTop = paddingTop + (parentHeight - flexLine.mMainSize) / 2f;
        childBottom = parentHeight - paddingBottom - (parentHeight - flexLine.mMainSize) / 2f;
        break;
    case JustifyContent.SPACE_AROUND:
        if (flexLine.mItemCount != 0) {
            spaceBetweenItem = (parentHeight - flexLine.mMainSize) / (float) flexLine.mItemCount;
        }
        childTop = paddingTop + spaceBetweenItem / 2f;
        childBottom = parentHeight - paddingBottom - spaceBetweenItem / 2f;
        break;
    case JustifyContent.SPACE_BETWEEN:
        childTop = paddingTop;
        float denominator = flexLine.mItemCount != 1 ? flexLine.mItemCount - 1 : 1f;
        spaceBetweenItem = (parentHeight - flexLine.mMainSize) / denominator;
        childBottom = parentHeight - paddingBottom;
        break;
    case JustifyContent.SPACE_EVENLY:
        if (flexLine.mItemCount != 0) {
            spaceBetweenItem = (parentHeight - flexLine.mMainSize) / (float) (flexLine.mItemCount + 1);
        }
        childTop = paddingTop + spaceBetweenItem;
        childBottom = parentHeight - paddingBottom - spaceBetweenItem;
        break;
    default:
        throw new IllegalStateException("Invalid justifyContent is set: " + mJustifyContent);
    }
    childTop -= mAnchorInfo.mPerpendicularCoordinate;
    childBottom -= mAnchorInfo.mPerpendicularCoordinate;
    spaceBetweenItem = Math.max(spaceBetweenItem, 0);

    // Used only when mLayoutDirection == LayoutState.LAYOUT_START to remember the index
    // a flex item should be inserted
    int indexInFlexLine = 0;
    for (int i = startPosition, itemCount = flexLine.getItemCount(); i < startPosition + itemCount; i++) {
        View view = getFlexItemAt(i);
        if (view == null) {
            continue;
        }

        // Retrieve the measure spec from the cache because the view may be re-created when
        // retrieved from Recycler, in that case measured width/height are set to 0 even
        // each visible child should be measured at least once in the FlexboxHelper
        long measureSpec = mFlexboxHelper.mMeasureSpecCache[i];
        int widthSpec = mFlexboxHelper.extractLowerInt(measureSpec);
        int heightSpec = mFlexboxHelper.extractHigherInt(measureSpec);
        LayoutParams lp = (LayoutParams) view.getLayoutParams();
        if (shouldMeasureChild(view, widthSpec, heightSpec, lp)) {
            view.measure(widthSpec, heightSpec);
        }

        childTop += (lp.topMargin + getTopDecorationHeight(view));
        childBottom -= (lp.rightMargin + getBottomDecorationHeight(view));

        if (layoutState.mLayoutDirection == LayoutState.LAYOUT_END) {
            calculateItemDecorationsForChild(view, TEMP_RECT);
            addView(view);
        } else {
            calculateItemDecorationsForChild(view, TEMP_RECT);
            addView(view, indexInFlexLine);
            indexInFlexLine++;
        }

        int leftWithDecoration = childLeft + getLeftDecorationWidth(view);
        int rightWithDecoration = childRight - getRightDecorationWidth(view);
        if (mIsRtl) {
            if (mFromBottomToTop) {
                mFlexboxHelper.layoutSingleChildVertical(view, flexLine, mIsRtl,
                        rightWithDecoration - view.getMeasuredWidth(),
                        Math.round(childBottom) - view.getMeasuredHeight(), rightWithDecoration,
                        Math.round(childBottom));
            } else {
                mFlexboxHelper.layoutSingleChildVertical(view, flexLine, mIsRtl,
                        rightWithDecoration - view.getMeasuredWidth(), Math.round(childTop),
                        rightWithDecoration, Math.round(childTop) + view.getMeasuredHeight());
            }
        } else {
            if (mFromBottomToTop) {
                mFlexboxHelper.layoutSingleChildVertical(view, flexLine, mIsRtl, leftWithDecoration,
                        Math.round(childBottom) - view.getMeasuredHeight(),
                        leftWithDecoration + view.getMeasuredWidth(), Math.round(childBottom));
            } else {
                mFlexboxHelper.layoutSingleChildVertical(view, flexLine, mIsRtl, leftWithDecoration,
                        Math.round(childTop), leftWithDecoration + view.getMeasuredWidth(),
                        Math.round(childTop) + view.getMeasuredHeight());
            }
        }
        childTop += (view.getMeasuredHeight() + lp.topMargin + getBottomDecorationHeight(view)
                + spaceBetweenItem);
        childBottom -= (view.getMeasuredHeight() + lp.bottomMargin + getTopDecorationHeight(view)
                + spaceBetweenItem);
    }
    layoutState.mFlexLinePosition += mLayoutState.mLayoutDirection;
    return flexLine.getCrossSize();
}

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  av  a  2 s  .  c om*/
 *
 * @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);
    }
}

From source file:android.support.v7.internal.widget.ActionBarView.java

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int childCount = getChildCount();
    if (mIsCollapsable) {
        int visibleChildren = 0;
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE && !(child == mMenuView && mMenuView.getChildCount() == 0)) {
                visibleChildren++;//  w w  w  . ja v a  2s. c  om
            }
        }

        if (visibleChildren == 0) {
            // No size for an empty action bar when collapsable.
            setMeasuredDimension(0, 0);
            mIsCollapsed = true;
            return;
        }
    }
    mIsCollapsed = false;

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    if (widthMode != MeasureSpec.EXACTLY) {
        throw new IllegalStateException(getClass().getSimpleName() + " can only be used "
                + "with android:layout_width=\"MATCH_PARENT\" (or fill_parent)");
    }

    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    if (heightMode != MeasureSpec.AT_MOST) {
        throw new IllegalStateException(getClass().getSimpleName() + " can only be used "
                + "with android:layout_height=\"wrap_content\"");
    }

    int contentWidth = MeasureSpec.getSize(widthMeasureSpec);

    int maxHeight = mContentHeight > 0 ? mContentHeight : MeasureSpec.getSize(heightMeasureSpec);

    final int verticalPadding = getPaddingTop() + getPaddingBottom();
    final int paddingLeft = getPaddingLeft();
    final int paddingRight = getPaddingRight();
    final int height = maxHeight - verticalPadding;
    final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);

    int availableWidth = contentWidth - paddingLeft - paddingRight;
    int leftOfCenter = availableWidth / 2;
    int rightOfCenter = leftOfCenter;

    HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;

    if (homeLayout.getVisibility() != GONE) {
        final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams();
        int homeWidthSpec;
        if (lp.width < 0) {
            homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
        } else {
            homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
        }
        homeLayout.measure(homeWidthSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
        final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getLeftOffset();
        availableWidth = Math.max(0, availableWidth - homeWidth);
        leftOfCenter = Math.max(0, availableWidth - homeWidth);
    }

    if (mMenuView != null && mMenuView.getParent() == this) {
        availableWidth = measureChildView(mMenuView, availableWidth, childSpecHeight, 0);
        rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth());
    }

    if (mIndeterminateProgressView != null && mIndeterminateProgressView.getVisibility() != GONE) {
        availableWidth = measureChildView(mIndeterminateProgressView, availableWidth, childSpecHeight, 0);
        rightOfCenter = Math.max(0, rightOfCenter - mIndeterminateProgressView.getMeasuredWidth());
    }

    final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE
            && (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;

    if (mExpandedActionView == null) {
        switch (mNavigationMode) {
        case ActionBar.NAVIGATION_MODE_LIST:
            if (mListNavLayout != null) {
                final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
                availableWidth = Math.max(0, availableWidth - itemPaddingSize);
                leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
                mListNavLayout.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
                final int listNavWidth = mListNavLayout.getMeasuredWidth();
                availableWidth = Math.max(0, availableWidth - listNavWidth);
                leftOfCenter = Math.max(0, leftOfCenter - listNavWidth);
            }
            break;
        case ActionBar.NAVIGATION_MODE_TABS:
            if (mTabScrollView != null) {
                final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
                availableWidth = Math.max(0, availableWidth - itemPaddingSize);
                leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
                mTabScrollView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
                final int tabWidth = mTabScrollView.getMeasuredWidth();
                availableWidth = Math.max(0, availableWidth - tabWidth);
                leftOfCenter = Math.max(0, leftOfCenter - tabWidth);
            }
            break;
        }
    }

    View customView = null;
    if (mExpandedActionView != null) {
        customView = mExpandedActionView;
    } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) {
        customView = mCustomNavView;
    }

    if (customView != null) {
        final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams());
        final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? (ActionBar.LayoutParams) lp
                : null;

        int horizontalMargin = 0;
        int verticalMargin = 0;
        if (ablp != null) {
            horizontalMargin = ablp.leftMargin + ablp.rightMargin;
            verticalMargin = ablp.topMargin + ablp.bottomMargin;
        }

        // If the action bar is wrapping to its content height, don't allow a custom
        // view to FILL_PARENT.
        int customNavHeightMode;
        if (mContentHeight <= 0) {
            customNavHeightMode = MeasureSpec.AT_MOST;
        } else {
            customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? MeasureSpec.EXACTLY
                    : MeasureSpec.AT_MOST;
        }
        final int customNavHeight = Math.max(0,
                (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin);

        final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? MeasureSpec.EXACTLY
                : MeasureSpec.AT_MOST;
        int customNavWidth = Math.max(0,
                (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth) - horizontalMargin);
        final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY)
                & Gravity.HORIZONTAL_GRAVITY_MASK;

        // Centering a custom view is treated specially; we try to center within the whole
        // action bar rather than in the available space.
        if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.FILL_PARENT) {
            customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2;
        }

        customView.measure(MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode),
                MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode));
        availableWidth -= horizontalMargin + customView.getMeasuredWidth();
    }

    if (mExpandedActionView == null && showTitle) {
        availableWidth = measureChildView(mTitleLayout, availableWidth,
                MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
        leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth());
    }

    if (mContentHeight <= 0) {
        int measuredHeight = 0;
        for (int i = 0; i < childCount; i++) {
            View v = getChildAt(i);
            int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
            if (paddedViewHeight > measuredHeight) {
                measuredHeight = paddedViewHeight;
            }
        }
        setMeasuredDimension(contentWidth, measuredHeight);
    } else {
        setMeasuredDimension(contentWidth, maxHeight);
    }

    if (mContextView != null) {
        mContextView.setContentHeight(getMeasuredHeight());
    }

    if (mProgressView != null && mProgressView.getVisibility() != GONE) {
        mProgressView.measure(
                MeasureSpec.makeMeasureSpec(contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST));
    }
}

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) {
        if (isInEditMode()) {
            // Don't crash the layout editor. Consume all of the space if specified
            // or pick a magic number from thin air otherwise.
            // TODO Better communication with tools of this bogus state.
            // It will crash on a real device.
            if (widthMode == MeasureSpec.AT_MOST) {
                widthMode = MeasureSpec.EXACTLY;
            } else if (widthMode == MeasureSpec.UNSPECIFIED) {
                widthMode = MeasureSpec.EXACTLY;
                widthSize = 300;//  ww  w.  java 2  s .c o m
            }
            if (heightMode == MeasureSpec.AT_MOST) {
                heightMode = MeasureSpec.EXACTLY;
            } else if (heightMode == MeasureSpec.UNSPECIFIED) {
                heightMode = MeasureSpec.EXACTLY;
                heightSize = 300;
            }
        } else {
            throw new IllegalArgumentException("DrawerLayout must be measured with MeasureSpec.EXACTLY.");
        }
    }

    setMeasuredDimension(widthSize, heightSize);

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

    // Only one drawer is permitted along each vertical edge (left / right). These two booleans
    // are tracking the presence of the edge drawers.
    boolean hasDrawerOnLeftEdge = false;
    boolean hasDrawerOnRightEdge = false;
    boolean hasDrawerOnBottomEdge = false;
    final int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = getChildAt(i);

        if (child.getVisibility() == GONE) {
            continue;
        }
        final @EdgeGravity int vchildGravity = getDrawerViewAbsoluteGravity(child)
                & Gravity.VERTICAL_GRAVITY_MASK;
        boolean isBottomEdgeDrawer = (vchildGravity == Gravity.BOTTOM);

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

        if (applyInsets && !isBottomEdgeDrawer) {
            final int cgrav = GravityCompat.getAbsoluteGravity(lp.gravity, layoutDirection);
            if (ViewCompat.getFitsSystemWindows(child)) {
                IMPL.dispatchChildInsets(child, mLastInsets, cgrav);
            } else {
                IMPL.applyMarginInsets(lp, mLastInsets, cgrav);
            }
        }

        if (isContentView(child)) {
            // Content views get measured at exactly the layout's size.
            final int contentWidthSpec = MeasureSpec.makeMeasureSpec(widthSize - lp.leftMargin - lp.rightMargin,
                    MeasureSpec.EXACTLY);
            final int contentHeightSpec = MeasureSpec
                    .makeMeasureSpec(heightSize - lp.topMargin - lp.bottomMargin, MeasureSpec.EXACTLY);
            child.measure(contentWidthSpec, contentHeightSpec);
        } else if (isDrawerView(child)) {
            if (SET_DRAWER_SHADOW_FROM_ELEVATION) {
                if (ViewCompat.getElevation(child) != mDrawerElevation) {
                    ViewCompat.setElevation(child, mDrawerElevation);
                }
            }
            final @EdgeGravity int childGravity = getDrawerViewAbsoluteGravity(child)
                    & Gravity.HORIZONTAL_GRAVITY_MASK;
            //                final @EdgeGravity int vchildGravity =
            //                        getDrawerViewAbsoluteGravity(child) & Gravity.VERTICAL_GRAVITY_MASK;
            // Note that the isDrawerView check guarantees that childGravity here is either
            // LEFT or RIGHT
            boolean isLeftEdgeDrawer = (childGravity == Gravity.LEFT);
            if ((isLeftEdgeDrawer && hasDrawerOnLeftEdge) || (isBottomEdgeDrawer && hasDrawerOnBottomEdge)
                    || (!isBottomEdgeDrawer && !isLeftEdgeDrawer && hasDrawerOnRightEdge)) {
                throw new IllegalStateException("Child drawer has absolute gravity "
                        + gravityToString(isBottomEdgeDrawer ? vchildGravity : childGravity) + " but this "
                        + TAG + " already has a " + "drawer view along that edge");
            }
            if (isBottomEdgeDrawer) {
                hasDrawerOnBottomEdge = true;
            } else if (isLeftEdgeDrawer) {
                hasDrawerOnLeftEdge = true;
            } else {
                hasDrawerOnRightEdge = true;
            }
            // View ???
            int minDrawerMargin = isBottomEdgeDrawer ? 0 : mMinDrawerMargin;
            final int drawerWidthSpec = getChildMeasureSpec(widthMeasureSpec,
                    minDrawerMargin + lp.leftMargin + lp.rightMargin, lp.width);
            final int drawerHeightSpec = getChildMeasureSpec(heightMeasureSpec, lp.topMargin + lp.bottomMargin,
                    lp.height);
            child.measure(drawerWidthSpec, drawerHeightSpec);
        } else {
            throw new IllegalStateException("Child " + child + " at index " + i
                    + " does not have a valid layout_gravity - must be Gravity.LEFT, "
                    + "Gravity.RIGHT, Gravity.BOTTOM or Gravity.NO_GRAVITY");
        }
    }
}