Example usage for android.view View getMeasuredHeight

List of usage examples for android.view View getMeasuredHeight

Introduction

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

Prototype

public final int getMeasuredHeight() 

Source Link

Document

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

Usage

From source file:com.aliasapps.seq.scroller.TwoWayView.java

/**
 * Measures the width of the given range of children (inclusive) and
 * returns the width with this TwoWayView's padding and item margin widths
 * included. If maxWidth is provided, the measuring will stop when the
 * current width reaches maxWidth.//from   w  w w .j av a  2  s. co  m
 *
 * @param heightMeasureSpec The height measure spec to be given to a child's
 *            {@link View#measure(int, int)}.
 * @param startPosition The position of the first child to be shown.
 * @param endPosition The (inclusive) position of the last child to be
 *            shown. Specify {@link #NO_POSITION} if the last child should be
 *            the last available child from the adapter.
 * @param maxWidth The maximum width that will be returned (if all the
 *            children don't fit in this value, this value will be
 *            returned).
 * @param disallowPartialChildPosition In general, whether the returned
 *            width should only contain entire children. This is more
 *            powerful--it is the first inclusive position at which partial
 *            children will not be allowed. Example: it looks nice to have
 *            at least 3 completely visible children, and in portrait this
 *            will most likely fit; but in landscape there could be times
 *            when even 2 children can not be completely shown, so a value
 *            of 2 (remember, inclusive) would be good (assuming
 *            startPosition is 0).
 * @return The width of this TwoWayView with the given children.
 */
private int measureWidthOfChildren(int heightMeasureSpec, int startPosition, int endPosition,
        final int maxWidth, int disallowPartialChildPosition) {

    final int paddingLeft = getPaddingLeft();
    final int paddingRight = getPaddingRight();

    final ListAdapter adapter = mAdapter;
    if (adapter == null) {
        return paddingLeft + paddingRight;
    }

    // Include the padding of the list
    int returnedWidth = paddingLeft + paddingRight;
    final int itemMargin = mItemMargin;

    // The previous height value that was less than maxHeight and contained
    // no partial children
    int prevWidthWithoutPartialChild = 0;
    int i;
    View child;

    // mItemCount - 1 since endPosition parameter is inclusive
    endPosition = (endPosition == NO_POSITION) ? adapter.getCount() - 1 : endPosition;
    final RecycleBin recycleBin = mRecycler;
    final boolean shouldRecycle = recycleOnMeasure();
    final boolean[] isScrap = mIsScrap;

    for (i = startPosition; i <= endPosition; ++i) {
        child = obtainView(i, isScrap);

        measureScrapChild(child, i, heightMeasureSpec);

        if (i > 0) {
            // Count the item margin for all but one child
            returnedWidth += itemMargin;
        }

        // Recycle the view before we possibly return from the method
        if (shouldRecycle) {
            recycleBin.addScrapView(child, -1);
        }

        returnedWidth += child.getMeasuredHeight();

        if (returnedWidth >= maxWidth) {
            // We went over, figure out which width to return.  If returnedWidth > maxWidth,
            // then the i'th position did not fit completely.
            return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1)
                    && (i > disallowPartialChildPosition) // We've past the min pos
                    && (prevWidthWithoutPartialChild > 0) // We have a prev width
                    && (returnedWidth != maxWidth) // i'th child did not fit completely
                            ? prevWidthWithoutPartialChild
                            : maxWidth;
        }

        if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) {
            prevWidthWithoutPartialChild = returnedWidth;
        }
    }

    // At this point, we went through the range of children, and they each
    // completely fit, so return the returnedWidth
    return returnedWidth;
}

From source file:com.aliasapps.seq.scroller.TwoWayView.java

/**
 * Measures the height of the given range of children (inclusive) and
 * returns the height with this TwoWayView's padding and item margin heights
 * included. If maxHeight is provided, the measuring will stop when the
 * current height reaches maxHeight./*from w w  w  .ja v  a  2 s.c  om*/
 *
 * @param widthMeasureSpec The width measure spec to be given to a child's
 *            {@link View#measure(int, int)}.
 * @param startPosition The position of the first child to be shown.
 * @param endPosition The (inclusive) position of the last child to be
 *            shown. Specify {@link #NO_POSITION} if the last child should be
 *            the last available child from the adapter.
 * @param maxHeight The maximum height that will be returned (if all the
 *            children don't fit in this value, this value will be
 *            returned).
 * @param disallowPartialChildPosition In general, whether the returned
 *            height should only contain entire children. This is more
 *            powerful--it is the first inclusive position at which partial
 *            children will not be allowed. Example: it looks nice to have
 *            at least 3 completely visible children, and in portrait this
 *            will most likely fit; but in landscape there could be times
 *            when even 2 children can not be completely shown, so a value
 *            of 2 (remember, inclusive) would be good (assuming
 *            startPosition is 0).
 * @return The height of this TwoWayView with the given children.
 */
private int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition,
        final int maxHeight, int disallowPartialChildPosition) {

    final int paddingTop = getPaddingTop();
    final int paddingBottom = getPaddingBottom();

    final ListAdapter adapter = mAdapter;
    if (adapter == null) {
        return paddingTop + paddingBottom;
    }

    // Include the padding of the list
    int returnedHeight = paddingTop + paddingBottom;
    final int itemMargin = mItemMargin;

    // The previous height value that was less than maxHeight and contained
    // no partial children
    int prevHeightWithoutPartialChild = 0;
    int i;
    View child;

    // mItemCount - 1 since endPosition parameter is inclusive
    endPosition = (endPosition == NO_POSITION) ? adapter.getCount() - 1 : endPosition;
    final RecycleBin recycleBin = mRecycler;
    final boolean shouldRecycle = recycleOnMeasure();
    final boolean[] isScrap = mIsScrap;

    for (i = startPosition; i <= endPosition; ++i) {
        child = obtainView(i, isScrap);

        measureScrapChild(child, i, widthMeasureSpec);

        if (i > 0) {
            // Count the item margin for all but one child
            returnedHeight += itemMargin;
        }

        // Recycle the view before we possibly return from the method
        if (shouldRecycle) {
            recycleBin.addScrapView(child, -1);
        }

        returnedHeight += child.getMeasuredHeight();

        if (returnedHeight >= maxHeight) {
            // We went over, figure out which height to return.  If returnedHeight > maxHeight,
            // then the i'th position did not fit completely.
            return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1)
                    && (i > disallowPartialChildPosition) // We've past the min pos
                    && (prevHeightWithoutPartialChild > 0) // We have a prev height
                    && (returnedHeight != maxHeight) // i'th child did not fit completely
                            ? prevHeightWithoutPartialChild
                            : maxHeight;
        }

        if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) {
            prevHeightWithoutPartialChild = returnedHeight;
        }
    }

    // At this point, we went through the range of children, and they each
    // completely fit, so return the returnedHeight
    return returnedHeight;
}

From source file:com.artifex.mupdf.view.ThumbnailViews.java

/**
 * Measures the width of the given range of children (inclusive) and returns
 * the width with this TwoWayView's padding and item margin widths included.
 * If maxWidth is provided, the measuring will stop when the current width
 * reaches maxWidth./* w  w w  . j  ava  2s  .  co  m*/
 * 
 * @param heightMeasureSpec
 *            The height measure spec to be given to a child's
 *            {@link View#measure(int, int)}.
 * @param startPosition
 *            The position of the first child to be shown.
 * @param endPosition
 *            The (inclusive) position of the last child to be shown.
 *            Specify {@link #NO_POSITION} if the last child should be the
 *            last available child from the adapter.
 * @param maxWidth
 *            The maximum width that will be returned (if all the children
 *            don't fit in this value, this value will be returned).
 * @param disallowPartialChildPosition
 *            In general, whether the returned width should only contain
 *            entire children. This is more powerful--it is the first
 *            inclusive position at which partial children will not be
 *            allowed. Example: it looks nice to have at least 3 completely
 *            visible children, and in portrait this will most likely fit;
 *            but in landscape there could be times when even 2 children can
 *            not be completely shown, so a value of 2 (remember, inclusive)
 *            would be good (assuming startPosition is 0).
 * @return The width of this TwoWayView with the given children.
 */
private int measureWidthOfChildren(int heightMeasureSpec, int startPosition, int endPosition,
        final int maxWidth, int disallowPartialChildPosition) {

    final int paddingLeft = getPaddingLeft();
    final int paddingRight = getPaddingRight();

    final ListAdapter adapter = mAdapter;
    if (adapter == null) {
        return paddingLeft + paddingRight;
    }

    // Include the padding of the list
    int returnedWidth = paddingLeft + paddingRight;
    final int itemMargin = mItemMargin;

    // The previous height value that was less than maxHeight and contained
    // no partial children
    int prevWidthWithoutPartialChild = 0;
    int i;
    View child;

    // mItemCount - 1 since endPosition parameter is inclusive
    endPosition = (endPosition == NO_POSITION) ? adapter.getCount() - 1 : endPosition;
    final RecycleBin recycleBin = mRecycler;
    final boolean shouldRecycle = recycleOnMeasure();
    final boolean[] isScrap = mIsScrap;

    for (i = startPosition; i <= endPosition; ++i) {
        child = obtainView(i, isScrap);

        measureScrapChild(child, i, heightMeasureSpec);

        if (i > 0) {
            // Count the item margin for all but one child
            returnedWidth += itemMargin;
        }

        // Recycle the view before we possibly return from the method
        if (shouldRecycle) {
            recycleBin.addScrapView(child, -1);
        }

        returnedWidth += child.getMeasuredHeight();

        if (returnedWidth >= maxWidth) {
            // We went over, figure out which width to return. If
            // returnedWidth > maxWidth,
            // then the i'th position did not fit completely.
            return (disallowPartialChildPosition >= 0) // Disallowing is
                    // enabled (> -1)
                    && (i > disallowPartialChildPosition) // We've past the
                    // min pos
                    && (prevWidthWithoutPartialChild > 0) // We have a prev
                    // width
                    && (returnedWidth != maxWidth) // i'th child did not fit
                            // completely
                            ? prevWidthWithoutPartialChild
                            : maxWidth;
        }

        if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) {
            prevWidthWithoutPartialChild = returnedWidth;
        }
    }

    // At this point, we went through the range of children, and they each
    // completely fit, so return the returnedWidth
    return returnedWidth;
}

From source file:com.artifex.mupdf.view.ThumbnailViews.java

/**
 * Measures the height of the given range of children (inclusive) and
 * returns the height with this TwoWayView's padding and item margin heights
 * included. If maxHeight is provided, the measuring will stop when the
 * current height reaches maxHeight.//from  www  . ja  v a 2 s .  c o m
 * 
 * @param widthMeasureSpec
 *            The width measure spec to be given to a child's
 *            {@link View#measure(int, int)}.
 * @param startPosition
 *            The position of the first child to be shown.
 * @param endPosition
 *            The (inclusive) position of the last child to be shown.
 *            Specify {@link #NO_POSITION} if the last child should be the
 *            last available child from the adapter.
 * @param maxHeight
 *            The maximum height that will be returned (if all the children
 *            don't fit in this value, this value will be returned).
 * @param disallowPartialChildPosition
 *            In general, whether the returned height should only contain
 *            entire children. This is more powerful--it is the first
 *            inclusive position at which partial children will not be
 *            allowed. Example: it looks nice to have at least 3 completely
 *            visible children, and in portrait this will most likely fit;
 *            but in landscape there could be times when even 2 children can
 *            not be completely shown, so a value of 2 (remember, inclusive)
 *            would be good (assuming startPosition is 0).
 * @return The height of this TwoWayView with the given children.
 */
private int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition,
        final int maxHeight, int disallowPartialChildPosition) {

    final int paddingTop = getPaddingTop();
    final int paddingBottom = getPaddingBottom();

    final ListAdapter adapter = mAdapter;
    if (adapter == null) {
        return paddingTop + paddingBottom;
    }

    // Include the padding of the list
    int returnedHeight = paddingTop + paddingBottom;
    final int itemMargin = mItemMargin;

    // The previous height value that was less than maxHeight and contained
    // no partial children
    int prevHeightWithoutPartialChild = 0;
    int i;
    View child;

    // mItemCount - 1 since endPosition parameter is inclusive
    endPosition = (endPosition == NO_POSITION) ? adapter.getCount() - 1 : endPosition;
    final RecycleBin recycleBin = mRecycler;
    final boolean shouldRecycle = recycleOnMeasure();
    final boolean[] isScrap = mIsScrap;

    for (i = startPosition; i <= endPosition; ++i) {
        child = obtainView(i, isScrap);

        measureScrapChild(child, i, widthMeasureSpec);

        if (i > 0) {
            // Count the item margin for all but one child
            returnedHeight += itemMargin;
        }

        // Recycle the view before we possibly return from the method
        if (shouldRecycle) {
            recycleBin.addScrapView(child, -1);
        }

        returnedHeight += child.getMeasuredHeight();

        if (returnedHeight >= maxHeight) {
            // We went over, figure out which height to return. If
            // returnedHeight > maxHeight,
            // then the i'th position did not fit completely.
            return (disallowPartialChildPosition >= 0) // Disallowing is
                    // enabled (> -1)
                    && (i > disallowPartialChildPosition) // We've past the
                    // min pos
                    && (prevHeightWithoutPartialChild > 0) // We have a prev
                    // height
                    && (returnedHeight != maxHeight) // i'th child did not
                            // fit completely
                            ? prevHeightWithoutPartialChild
                            : maxHeight;
        }

        if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) {
            prevHeightWithoutPartialChild = returnedHeight;
        }
    }

    // At this point, we went through the range of children, and they each
    // completely fit, so return the returnedHeight
    return returnedHeight;
}

From source file:com.aliasapps.seq.scroller.TwoWayView.java

@TargetApi(11)
private void setupChild(View child, int position, int top, int left, boolean flow, boolean selected,
        boolean recycled) {
    final boolean isSelected = selected && shouldShowSelector();
    final boolean updateChildSelected = isSelected != child.isSelected();
    final int touchMode = mTouchMode;

    final boolean isPressed = touchMode > TOUCH_MODE_DOWN && touchMode < TOUCH_MODE_DRAGGING
            && mMotionPosition == position;

    final boolean updateChildPressed = isPressed != child.isPressed();
    final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();

    // Respect layout params that are already in the view. Otherwise make some up...
    LayoutParams lp = (LayoutParams) child.getLayoutParams();
    if (lp == null) {
        lp = generateDefaultLayoutParams();
    }//from   www  . j  a  v  a2s  .  c om

    lp.viewType = mAdapter.getItemViewType(position);

    if (recycled && !lp.forceAdd) {
        attachViewToParent(child, (flow ? -1 : 0), lp);
    } else {
        lp.forceAdd = false;
        addViewInLayout(child, (flow ? -1 : 0), lp, true);
    }

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

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

    if (mChoiceMode.compareTo(ChoiceMode.NONE) != 0 && mCheckStates != null) {
        if (child instanceof Checkable) {
            ((Checkable) child).setChecked(mCheckStates.get(position));
        } else if (getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
            child.setActivated(mCheckStates.get(position));
        }
    }

    if (needToMeasure) {
        measureChild(child, lp);
    } else {
        cleanupLayoutState(child);
    }

    final int w = child.getMeasuredWidth();
    final int h = child.getMeasuredHeight();

    final int childTop = (mIsVertical && !flow ? top - h : top);
    final int childLeft = (!mIsVertical && !flow ? left - w : left);

    if (needToMeasure) {
        final int childRight = childLeft + w;
        final int childBottom = childTop + h;

        child.layout(childLeft, childTop, childRight, childBottom);
    } else {
        child.offsetLeftAndRight(childLeft - child.getLeft());
        child.offsetTopAndBottom(childTop - child.getTop());
    }
}

From source file:com.artifex.mupdf.view.ThumbnailViews.java

@TargetApi(11)
private void setupChild(View child, int position, int top, int left, boolean flow, boolean selected,
        boolean recycled) {
    final boolean isSelected = selected && shouldShowSelector();
    final boolean updateChildSelected = isSelected != child.isSelected();
    final int touchMode = mTouchMode;

    final boolean isPressed = touchMode > TOUCH_MODE_DOWN && touchMode < TOUCH_MODE_DRAGGING
            && mMotionPosition == position;

    final boolean updateChildPressed = isPressed != child.isPressed();
    final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();

    // Respect layout params that are already in the view. Otherwise make
    // some up...
    LayoutParams lp = (LayoutParams) child.getLayoutParams();
    if (lp == null) {
        lp = generateDefaultLayoutParams();
    }//w ww  .  ja v  a  2  s. co m

    lp.viewType = mAdapter.getItemViewType(position);

    if (recycled && !lp.forceAdd) {
        attachViewToParent(child, (flow ? -1 : 0), lp);
    } else {
        lp.forceAdd = false;
        addViewInLayout(child, (flow ? -1 : 0), lp, true);
    }

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

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

    if (mChoiceMode.compareTo(ChoiceMode.NONE) != 0 && mCheckStates != null) {
        if (child instanceof Checkable) {
            ((Checkable) child).setChecked(mCheckStates.get(position));
        } else if (getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
            child.setActivated(mCheckStates.get(position));
        }
    }

    if (needToMeasure) {
        measureChild(child, lp);
    } else {
        cleanupLayoutState(child);
    }

    final int w = child.getMeasuredWidth();
    final int h = child.getMeasuredHeight();

    final int childTop = (mIsVertical && !flow ? top - h : top);
    final int childLeft = (!mIsVertical && !flow ? left - w : left);

    if (needToMeasure) {
        final int childRight = childLeft + w;
        final int childBottom = childTop + h;

        child.layout(childLeft, childTop, childRight, childBottom);
    } else {
        child.offsetLeftAndRight(childLeft - child.getLeft());
        child.offsetTopAndBottom(childTop - child.getTop());
    }
}

From source file:com.artifex.mupdflib.TwoWayView.java

@TargetApi(11)
private void setupChild(View child, int position, int top, int left, boolean flow, boolean selected,
        boolean recycled) {
    final boolean isSelected = selected && shouldShowSelector();
    final boolean updateChildSelected = isSelected != child.isSelected();
    final int touchMode = mTouchMode;

    final boolean isPressed = touchMode > TOUCH_MODE_DOWN && touchMode < TOUCH_MODE_DRAGGING
            && mMotionPosition == position;

    final boolean updateChildPressed = isPressed != child.isPressed();
    final boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested();

    // Respect layout params that are already in the view. Otherwise make some up...
    LayoutParams lp = (LayoutParams) child.getLayoutParams();
    if (lp == null) {
        lp = generateDefaultLayoutParams();
    }//  w  w w.j av  a2s  . c  o m

    lp.viewType = mAdapter.getItemViewType(position);

    if (recycled && !lp.forceAdd) {
        attachViewToParent(child, (flow ? -1 : 0), lp);
    } else {
        lp.forceAdd = false;
        addViewInLayout(child, (flow ? -1 : 0), lp, true);
    }

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

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

    if (mChoiceMode != ChoiceMode.NONE && mCheckStates != null) {
        if (child instanceof Checkable) {
            ((Checkable) child).setChecked(mCheckStates.get(position));
        } else if (Build.VERSION.SDK_INT >= HONEYCOMB) {
            child.setActivated(mCheckStates.get(position));
        }
    }

    if (needToMeasure) {
        measureChild(child, lp);
    } else {
        cleanupLayoutState(child);
    }

    final int w = child.getMeasuredWidth();
    final int h = child.getMeasuredHeight();

    final int childTop = (mIsVertical && !flow ? top - h : top);
    final int childLeft = (!mIsVertical && !flow ? left - w : left);

    if (needToMeasure) {
        final int childRight = childLeft + w;
        final int childBottom = childTop + h;

        child.layout(childLeft, childTop, childRight, childBottom);
    } else {
        child.offsetLeftAndRight(childLeft - child.getLeft());
        child.offsetTopAndBottom(childTop - child.getTop());
    }
}

From source file:app.umitems.greenclock.widget.sgv.StaggeredGridView.java

/**
 * Measure and layout all currently visible children.
 *
 * @param queryAdapter true to requery the adapter for view data
 *//*from  w  ww .  j  a  v  a  2s  .c o m*/
final void layoutChildren(boolean queryAdapter) {
    final int paddingLeft = getPaddingLeft();
    final int paddingRight = getPaddingRight();
    final int itemMargin = mItemMargin;
    final int availableWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1));
    final int colWidth = availableWidth / mColCount;
    // The availableWidth may not be divisible by mColCount. Keep the
    // remainder. It will be added to the width of the last view in the row.
    final int remainder = availableWidth % mColCount;

    boolean viewsRemovedInLayout = false;

    // If we're animating out stale views, then we want to defer recycling of views.
    final boolean deferRecyclingForAnimation = mAnimationOutMode != AnimationOut.NONE;

    if (!deferRecyclingForAnimation) {
        final int childCount = getChildCount();
        // If the latest data set has fewer data items than mFirstPosition, don't keep any
        // views on screen, and just let the layout logic below retrieve appropriate views
        // from the recycler.
        final int viewsToKeepOnScreen = (mItemCount <= mFirstPosition) ? 0 : mItemCount - mFirstPosition;

        if (childCount > viewsToKeepOnScreen) {
            // If there are more views laid out than the number of data items remaining to be
            // laid out, recycle the extraneous views.
            recycleViewsInRange(viewsToKeepOnScreen, childCount - 1);
            viewsRemovedInLayout = true;
        }
    } else {
        mViewsToAnimateOut.clear();
    }

    for (int i = 0; i < getChildCount(); i++) {
        final int position = mFirstPosition + i;
        View child = getChildAt(i);

        final int highestAvailableLayoutPosition = mItemBottoms[getNextColumnDown()];
        if (deferRecyclingForAnimation
                && (position >= mItemCount || highestAvailableLayoutPosition >= getHeight())) {
            // For the remainder of views on screen, they should not be on screen, so we can
            // skip layout.  Add them to the list of views to animate out.
            // We should only get in this position if deferRecyclingForAnimation = true,
            // otherwise, we should've recycled all views before getting into this layout loop.
            mViewsToAnimateOut.add(child);
            continue;
        }

        LayoutParams lp = null;
        int col = -1;

        if (child != null) {
            lp = (LayoutParams) child.getLayoutParams();
            col = lp.column;
        }

        final boolean needsLayout = queryAdapter || child == null || child.isLayoutRequested();
        if (queryAdapter) {
            View newView = null;
            if (deferRecyclingForAnimation) {
                // If we are deferring recycling for animation, then we don't want to pass the
                // current child in to obtainView for re-use.  obtainView() in this case should
                // try to find the view belonging to this item on screen, or populate a fresh
                // one from the recycler.
                newView = obtainView(position);
            } else {
                newView = obtainView(position, child);
            }

            // Update layout params since they may have changed
            lp = (LayoutParams) newView.getLayoutParams();

            if (newView != child) {
                if (child != null && !deferRecyclingForAnimation) {
                    mRecycler.addScrap(child);
                    removeViewInLayout(child);
                    viewsRemovedInLayout = true;
                }

                // If this view is already in the layout hierarchy, we can just detach it
                // from the parent and re-attach it at the correct index.  If the view has
                // already been removed from the layout hierarchy, getParent() == null.
                if (newView.getParent() == this) {
                    detachViewFromParent(newView);
                    attachViewToParent(newView, i, lp);
                } else {
                    addViewInLayout(newView, i, lp);
                }
            }

            child = newView;

            // Since the data has changed, we need to make sure the next child is in the
            // right column. We choose the next column down (vs. next column up) because we
            // are filling from the top of the screen downwards as we iterate through
            // visible children. (We take span into account below.)
            lp.column = getNextColumnDown();
            col = lp.column;
        }

        setReorderingArea(lp);

        final int span = Math.min(mColCount, lp.span);

        // Given the span, check if there's enough space to put this view at this column.
        // IMPORTANT Propagate the same logic to {@link #calculateLayoutStartOffsets}.
        if (span > 1) {
            if (mIsRtlLayout) {
                // For RTL layout, if the current column index is less than the span of the
                // child, then we know that there is not enough room remaining to lay this
                // child out (e.g., if col == 0, but span == 2, then laying this child down
                // at column = col would put us out of bound into a negative column index.).
                // For this scenario, reset the index back to the right-most column, and lay
                // out the child at this position where we can ensure that we can display as
                // much of the child as possible.
                if (col + 1 < span) {
                    col = mColCount - 1;
                }
            } else {
                if (mColCount - col < span) {
                    // If not, reset the col to 0.
                    col = 0;
                }
            }

            lp.column = col;
        }

        int widthSize = (colWidth * span + itemMargin * (span - 1));
        // If it is rtl, we layout the view from col to col - span +
        // 1. If it reaches the most left column, i.e. we added the
        // additional width. So the check it span == col +1
        if ((mIsRtlLayout && span == col + 1) || (!mIsRtlLayout && span + col == mColCount)) {
            widthSize += remainder;
        }
        if (needsLayout) {
            final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);

            final int heightSpec;
            if (lp.height == LayoutParams.WRAP_CONTENT) {
                heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
            } else {
                heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
            }

            child.measure(widthSpec, heightSpec);
        }

        // Place the top of this child beneath the last by finding the lowest coordinate across
        // the columns that this child will span.  For LTR layout, we scan across from left to
        // right, and for RTL layout, we scan from right to left.
        // TODO:  Consolidate this logic with getNextRecordDown() in the future, as that method
        // already calculates the margins for us.  This will keep the implementation consistent
        // with fillUp() and fillDown().
        int childTop = mItemBottoms[col] + mItemMargin;
        if (span > 1) {
            int lowest = childTop;
            for (int spanIndex = 0; spanIndex < span; spanIndex++) {
                final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
                final int bottom = mItemBottoms[index] + mItemMargin;
                if (bottom > lowest) {
                    lowest = bottom;
                }
            }

            childTop = lowest;
        }

        final int childHeight = child.getMeasuredHeight();
        final int childBottom = childTop + childHeight;
        int childLeft = 0;
        int childRight = 0;
        if (mIsRtlLayout) {
            childRight = (getWidth() - paddingRight) - (mColCount - col - 1) * (colWidth + itemMargin);
            childLeft = childRight - child.getMeasuredWidth();
        } else {
            childLeft = paddingLeft + col * (colWidth + itemMargin);
            childRight = childLeft + child.getMeasuredWidth();
        }

        /*    Log.v(TAG, "[layoutChildren] height: " + childHeight
            + " top: " + childTop + " bottom: " + childBottom
            + " left: " + childLeft
            + " column: " + col
            + " position: " + position
            + " id: " + lp.id);
        */
        child.layout(childLeft, childTop, childRight, childBottom);
        if (lp.id == mFocusedChildIdToScrollIntoView) {
            child.requestFocus();
        }

        for (int spanIndex = 0; spanIndex < span; spanIndex++) {
            final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
            mItemBottoms[index] = childBottom;
        }

        // Whether or not LayoutRecords may have already existed for the view at this position
        // on screen, we'll update it after we lay out to ensure that the LayoutRecord
        // has the most updated information about the view at this position.  We can be assured
        // that all views before those on screen (views with adapter position < mFirstPosition)
        // have the correct LayoutRecords because calculateLayoutStartOffsets() would have
        // set them appropriately.
        LayoutRecord rec = mLayoutRecords.get(position);
        if (rec == null) {
            rec = new LayoutRecord();
            mLayoutRecords.put(position, rec);
        }

        rec.column = lp.column;
        rec.height = childHeight;
        rec.id = lp.id;
        rec.span = span;
    }

    // It appears that removeViewInLayout() does not invalidate.  So if we make use of this
    // method during layout, we should invalidate explicitly.
    if (viewsRemovedInLayout || deferRecyclingForAnimation) {
        invalidate();
    }
}

From source file:com.deepak.myclock.widget.sgv.StaggeredGridView.java

/**
 * Measure and layout all currently visible children.
 *
 * @param queryAdapter true to requery the adapter for view data
 *//*from  www  . ja v a2 s  . c o m*/
final void layoutChildren(boolean queryAdapter) {
    final int paddingLeft = getPaddingLeft();
    final int paddingRight = getPaddingRight();
    final int itemMargin = mItemMargin;
    final int availableWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1));
    final int colWidth = availableWidth / mColCount;
    // The availableWidth may not be divisible by mColCount. Keep the
    // remainder. It will be added to the width of the last view in the row.
    final int remainder = availableWidth % mColCount;

    boolean viewsRemovedInLayout = false;

    // If we're animating out stale views, then we want to defer recycling of views.
    final boolean deferRecyclingForAnimation = mAnimationOutMode != SgvAnimationHelper.AnimationOut.NONE;

    if (!deferRecyclingForAnimation) {
        final int childCount = getChildCount();
        // If the latest data set has fewer data items than mFirstPosition, don't keep any
        // views on screen, and just let the layout logic below retrieve appropriate views
        // from the recycler.
        final int viewsToKeepOnScreen = (mItemCount <= mFirstPosition) ? 0 : mItemCount - mFirstPosition;

        if (childCount > viewsToKeepOnScreen) {
            // If there are more views laid out than the number of data items remaining to be
            // laid out, recycle the extraneous views.
            recycleViewsInRange(viewsToKeepOnScreen, childCount - 1);
            viewsRemovedInLayout = true;
        }
    } else {
        mViewsToAnimateOut.clear();
    }

    for (int i = 0; i < getChildCount(); i++) {
        final int position = mFirstPosition + i;
        View child = getChildAt(i);

        final int highestAvailableLayoutPosition = mItemBottoms[getNextColumnDown()];
        if (deferRecyclingForAnimation
                && (position >= mItemCount || highestAvailableLayoutPosition >= getHeight())) {
            // For the remainder of views on screen, they should not be on screen, so we can
            // skip layout.  Add them to the list of views to animate out.
            // We should only get in this position if deferRecyclingForAnimation = true,
            // otherwise, we should've recycled all views before getting into this layout loop.
            mViewsToAnimateOut.add(child);
            continue;
        }

        LayoutParams lp = null;
        int col = -1;

        if (child != null) {
            lp = (LayoutParams) child.getLayoutParams();
            col = lp.column;
        }

        final boolean needsLayout = queryAdapter || child == null || child.isLayoutRequested();
        if (queryAdapter) {
            View newView = null;
            if (deferRecyclingForAnimation) {
                // If we are deferring recycling for animation, then we don't want to pass the
                // current child in to obtainView for re-use.  obtainView() in this case should
                // try to find the view belonging to this item on screen, or populate a fresh
                // one from the recycler.
                newView = obtainView(position);
            } else {
                newView = obtainView(position, child);
            }

            // Update layout params since they may have changed
            lp = (LayoutParams) newView.getLayoutParams();

            if (newView != child) {
                if (child != null && !deferRecyclingForAnimation) {
                    mRecycler.addScrap(child);
                    removeViewInLayout(child);
                    viewsRemovedInLayout = true;
                }

                // If this view is already in the layout hierarchy, we can just detach it
                // from the parent and re-attach it at the correct index.  If the view has
                // already been removed from the layout hierarchy, getParent() == null.
                if (newView.getParent() == this) {
                    detachViewFromParent(newView);
                    attachViewToParent(newView, i, lp);
                } else {
                    addViewInLayout(newView, i, lp);
                }
            }

            child = newView;

            // Since the data has changed, we need to make sure the next child is in the
            // right column. We choose the next column down (vs. next column up) because we
            // are filling from the top of the screen downwards as we iterate through
            // visible children. (We take span into account below.)
            lp.column = getNextColumnDown();
            col = lp.column;
        }

        setReorderingArea(lp);

        final int span = Math.min(mColCount, lp.span);

        // Given the span, check if there's enough space to put this view at this column.
        // IMPORTANT Propagate the same logic to {@link #calculateLayoutStartOffsets}.
        if (span > 1) {
            if (mIsRtlLayout) {
                // For RTL layout, if the current column index is less than the span of the
                // child, then we know that there is not enough room remaining to lay this
                // child out (e.g., if col == 0, but span == 2, then laying this child down
                // at column = col would put us out of bound into a negative column index.).
                // For this scenario, reset the index back to the right-most column, and lay
                // out the child at this position where we can ensure that we can display as
                // much of the child as possible.
                if (col + 1 < span) {
                    col = mColCount - 1;
                }
            } else {
                if (mColCount - col < span) {
                    // If not, reset the col to 0.
                    col = 0;
                }
            }

            lp.column = col;
        }

        int widthSize = (colWidth * span + itemMargin * (span - 1));
        // If it is rtl, we layout the view from col to col - span +
        // 1. If it reaches the most left column, i.e. we added the
        // additional width. So the check it span == col +1
        if ((mIsRtlLayout && span == col + 1) || (!mIsRtlLayout && span + col == mColCount)) {
            widthSize += remainder;
        }
        if (needsLayout) {
            final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);

            final int heightSpec;
            if (lp.height == LayoutParams.WRAP_CONTENT) {
                heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
            } else {
                heightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
            }

            child.measure(widthSpec, heightSpec);
        }

        // Place the top of this child beneath the last by finding the lowest coordinate across
        // the columns that this child will span.  For LTR layout, we scan across from left to
        // right, and for RTL layout, we scan from right to left.
        // TODO:  Consolidate this logic with getNextRecordDown() in the future, as that method
        // already calculates the margins for us.  This will keep the implementation consistent
        // with fillUp() and fillDown().
        int childTop = mItemBottoms[col] + mItemMargin;
        if (span > 1) {
            int lowest = childTop;
            for (int spanIndex = 0; spanIndex < span; spanIndex++) {
                final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
                final int bottom = mItemBottoms[index] + mItemMargin;
                if (bottom > lowest) {
                    lowest = bottom;
                }
            }

            childTop = lowest;
        }

        final int childHeight = child.getMeasuredHeight();
        final int childBottom = childTop + childHeight;
        int childLeft = 0;
        int childRight = 0;
        if (mIsRtlLayout) {
            childRight = (getWidth() - paddingRight) - (mColCount - col - 1) * (colWidth + itemMargin);
            childLeft = childRight - child.getMeasuredWidth();
        } else {
            childLeft = paddingLeft + col * (colWidth + itemMargin);
            childRight = childLeft + child.getMeasuredWidth();
        }

        /*    Log.v(TAG, "[layoutChildren] height: " + childHeight
            + " top: " + childTop + " bottom: " + childBottom
            + " left: " + childLeft
            + " column: " + col
            + " position: " + position
            + " id: " + lp.id);
        */
        child.layout(childLeft, childTop, childRight, childBottom);
        if (lp.id == mFocusedChildIdToScrollIntoView) {
            child.requestFocus();
        }

        for (int spanIndex = 0; spanIndex < span; spanIndex++) {
            final int index = mIsRtlLayout ? col - spanIndex : col + spanIndex;
            mItemBottoms[index] = childBottom;
        }

        // Whether or not LayoutRecords may have already existed for the view at this position
        // on screen, we'll update it after we lay out to ensure that the LayoutRecord
        // has the most updated information about the view at this position.  We can be assured
        // that all views before those on screen (views with adapter position < mFirstPosition)
        // have the correct LayoutRecords because calculateLayoutStartOffsets() would have
        // set them appropriately.
        LayoutRecord rec = mLayoutRecords.get(position);
        if (rec == null) {
            rec = new LayoutRecord();
            mLayoutRecords.put(position, rec);
        }

        rec.column = lp.column;
        rec.height = childHeight;
        rec.id = lp.id;
        rec.span = span;
    }

    // It appears that removeViewInLayout() does not invalidate.  So if we make use of this
    // method during layout, we should invalidate explicitly.
    if (viewsRemovedInLayout || deferRecyclingForAnimation) {
        invalidate();
    }
}