List of usage examples for android.view View measure
public final void measure(int widthMeasureSpec, int heightMeasureSpec)
This is called to find out how big a view should be.
From source file:com.android.leanlauncher.Workspace.java
public Bitmap createWidgetBitmap(ItemInfo widgetInfo, View layout) { int[] unScaledSize = estimateItemSize(widgetInfo.spanX, widgetInfo.spanY, false); int visibility = layout.getVisibility(); layout.setVisibility(VISIBLE);/* w w w .ja va2s.c o m*/ int width = MeasureSpec.makeMeasureSpec(unScaledSize[0], MeasureSpec.EXACTLY); int height = MeasureSpec.makeMeasureSpec(unScaledSize[1], MeasureSpec.EXACTLY); Bitmap b = Bitmap.createBitmap(unScaledSize[0], unScaledSize[1], Bitmap.Config.ARGB_8888); mCanvas.setBitmap(b); layout.measure(width, height); layout.layout(0, 0, unScaledSize[0], unScaledSize[1]); layout.draw(mCanvas); mCanvas.setBitmap(null); layout.setVisibility(visibility); return b; }
From source file:com.aigo.kt03airdemo.ui.view.ResideLayout.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()) { if (widthMode == MeasureSpec.UNSPECIFIED) { widthSize = 300;/*from www. ja v a 2s . co m*/ } } else { throw new IllegalStateException("Width must have an exact value or MATCH_PARENT"); } } else if (heightMode == MeasureSpec.UNSPECIFIED) { if (isInEditMode()) { 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; } 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 > widthAvailable || 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(widthAvailable, 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:com.bright.cloudutils.view.ResideLayout.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()) { if (widthMode == MeasureSpec.UNSPECIFIED) { widthSize = 300;//from ww w . j a v a 2 s. c o m } } else { throw new IllegalStateException("Width must have an exact value or MATCH_PARENT"); } } else if (heightMode == MeasureSpec.UNSPECIFIED) { if (isInEditMode()) { 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; } 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 > widthAvailable || 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(widthAvailable, 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:com.google.android.flexbox.FlexboxHelper.java
/** * Expand the view horizontally to the size of the crossSize (considering the view margins) * * @param view the View to be stretched * @param crossSize the cross size// ww w . j a v a 2 s . com * @param index the index of the view */ private void stretchViewHorizontally(View view, int crossSize, int index) { FlexItem flexItem = (FlexItem) view.getLayoutParams(); int newWidth = crossSize - flexItem.getMarginLeft() - flexItem.getMarginRight() - mFlexContainer.getDecorationLengthCrossAxis(view); newWidth = Math.max(newWidth, flexItem.getMinWidth()); newWidth = Math.min(newWidth, flexItem.getMaxWidth()); int childHeightSpec; int measuredHeight; if (mMeasuredSizeCache != null) { // Retrieve the measured height from the cache because there // are some cases that the view is re-created from the last measure, thus // View#getMeasuredHeight returns 0. // E.g. if the flex container is FlexboxLayoutManager, that case happens // frequently measuredHeight = extractHigherInt(mMeasuredSizeCache[index]); } else { measuredHeight = view.getMeasuredHeight(); } childHeightSpec = View.MeasureSpec.makeMeasureSpec(measuredHeight, View.MeasureSpec.EXACTLY); int childWidthSpec = View.MeasureSpec.makeMeasureSpec(newWidth, View.MeasureSpec.EXACTLY); view.measure(childWidthSpec, childHeightSpec); updateMeasureCache(index, childWidthSpec, childHeightSpec, view); mFlexContainer.updateViewCache(index, view); }
From source file:com.google.android.flexbox.FlexboxHelper.java
/** * Expand the view vertically to the size of the crossSize (considering the view margins) * * @param view the View to be stretched * @param crossSize the cross size//from w w w. j av a 2 s . co m * @param index the index of the view */ private void stretchViewVertically(View view, int crossSize, int index) { FlexItem flexItem = (FlexItem) view.getLayoutParams(); int newHeight = crossSize - flexItem.getMarginTop() - flexItem.getMarginBottom() - mFlexContainer.getDecorationLengthCrossAxis(view); newHeight = Math.max(newHeight, flexItem.getMinHeight()); newHeight = Math.min(newHeight, flexItem.getMaxHeight()); int childWidthSpec; int measuredWidth; if (mMeasuredSizeCache != null) { // Retrieve the measured height from the cache because there // are some cases that the view is re-created from the last measure, thus // View#getMeasuredHeight returns 0. // E.g. if the flex container is FlexboxLayoutManager, that case happens // frequently measuredWidth = extractLowerInt(mMeasuredSizeCache[index]); } else { measuredWidth = view.getMeasuredWidth(); } childWidthSpec = View.MeasureSpec.makeMeasureSpec(measuredWidth, View.MeasureSpec.EXACTLY); int childHeightSpec = View.MeasureSpec.makeMeasureSpec(newHeight, View.MeasureSpec.EXACTLY); view.measure(childWidthSpec, childHeightSpec); updateMeasureCache(index, childWidthSpec, childHeightSpec, view); mFlexContainer.updateViewCache(index, view); }
From source file:com.irontec.jaigiro.widgets.StaggeredGridView.java
/** * Measure and layout all currently visible children. * //ww w. j a v a2 s . co m * @param queryAdapter * true to requery the adapter for view data */ final void layoutChildren(boolean queryAdapter) { final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int itemMargin = mItemMargin; final int colWidth = (getWidth() - paddingLeft - paddingRight - itemMargin * (mColCount - 1)) / mColCount; int rebuildLayoutRecordsBefore = -1; int rebuildLayoutRecordsAfter = -1; Arrays.fill(mItemBottoms, Integer.MIN_VALUE); final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int col = lp.column; final int position = mFirstPosition + i; final boolean needsLayout = queryAdapter || child.isLayoutRequested(); if (queryAdapter) { View newView = obtainView(position, child); if (newView != child) { removeViewAt(i); addView(newView, i); child = newView; } lp = (LayoutParams) child.getLayoutParams(); // Might have // changed } final int span = Math.min(mColCount, lp.span); final int widthSize = colWidth * span + itemMargin * (span - 1); 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); } int childTop = mItemBottoms[col] > Integer.MIN_VALUE ? mItemBottoms[col] + mItemMargin : child.getTop(); if (span > 1) { int lowest = childTop; for (int j = col + 1; j < col + span; j++) { final int bottom = mItemBottoms[j] + mItemMargin; if (bottom > lowest) { lowest = bottom; } } childTop = lowest; } final int childHeight = child.getMeasuredHeight(); final int childBottom = childTop + childHeight; final int childLeft = paddingLeft + col * (colWidth + itemMargin); final int childRight = childLeft + child.getMeasuredWidth(); child.layout(childLeft, childTop, childRight, childBottom); for (int j = col; j < col + span; j++) { mItemBottoms[j] = childBottom; } final LayoutRecord rec = mLayoutRecords.get(position); if (rec != null && rec.height != childHeight) { // Invalidate our layout records for everything before this. rec.height = childHeight; rebuildLayoutRecordsBefore = position; } if (rec != null && rec.span != span) { // Invalidate our layout records for everything after this. rec.span = span; rebuildLayoutRecordsAfter = position; } } // Update mItemBottoms for any empty columns for (int i = 0; i < mColCount; i++) { if (mItemBottoms[i] == Integer.MIN_VALUE) { mItemBottoms[i] = mItemTops[i]; } } if (rebuildLayoutRecordsBefore >= 0 || rebuildLayoutRecordsAfter >= 0) { if (rebuildLayoutRecordsBefore >= 0) { invalidateLayoutRecordsBeforePosition(rebuildLayoutRecordsBefore); } if (rebuildLayoutRecordsAfter >= 0) { invalidateLayoutRecordsAfterPosition(rebuildLayoutRecordsAfter); } for (int i = 0; i < childCount; i++) { final int position = mFirstPosition + i; final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); LayoutRecord rec = mLayoutRecords.get(position); if (rec == null) { rec = new LayoutRecord(); mLayoutRecords.put(position, rec); } rec.column = lp.column; rec.height = child.getHeight(); rec.id = lp.id; rec.span = Math.min(mColCount, lp.span); } } }
From source file:android.support.v7.widget.StaggeredGridLayoutManager.java
private void measureChildWithDecorationsAndMargin(View child, int widthSpec, int heightSpec) { 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); child.measure(widthSpec, heightSpec); }
From source file:com.android.dialer.widget.OverlappingPaneLayout.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;/*from w ww . ja v a 2s .c o 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 layoutWidth = 0; int maxLayoutWidth = -1; switch (widthMode) { case MeasureSpec.EXACTLY: layoutWidth = maxLayoutWidth = widthSize - getPaddingLeft() - getPaddingRight(); break; case MeasureSpec.AT_MOST: maxLayoutWidth = widthSize - getPaddingLeft() - getPaddingRight(); break; } float weightSum = 0; boolean canSlide = false; final int heightAvailable = heightSize - getPaddingTop() - getPaddingBottom(); int heightRemaining = heightAvailable; 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) { continue; } if (lp.weight > 0) { weightSum += lp.weight; // If we have no height, weight is the only contributor to the final size. // Measure this view on the weight pass only. if (lp.height == 0) continue; } int childHeightSpec; final int verticalMargin = lp.topMargin + lp.bottomMargin; if (lp.height == LayoutParams.WRAP_CONTENT) { childHeightSpec = MeasureSpec.makeMeasureSpec(heightAvailable - verticalMargin, MeasureSpec.AT_MOST); } else if (lp.height == LayoutParams.MATCH_PARENT) { childHeightSpec = MeasureSpec.makeMeasureSpec(heightAvailable - verticalMargin, MeasureSpec.EXACTLY); } else { childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); } int childWidthSpec; if (lp.width == LayoutParams.WRAP_CONTENT) { childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.AT_MOST); } else if (lp.width == LayoutParams.MATCH_PARENT) { childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.EXACTLY); } else { childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); } child.measure(childWidthSpec, childHeightSpec); final int childWidth = child.getMeasuredWidth(); final int childHeight = child.getMeasuredHeight(); if (widthMode == MeasureSpec.AT_MOST && childWidth > layoutWidth) { layoutWidth = Math.min(childWidth, maxLayoutWidth); } heightRemaining -= childHeight; canSlide |= lp.slideable = heightRemaining < 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 fixedPanelHeightLimit = heightAvailable - 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.height == 0 && lp.weight > 0; final int measuredHeight = skippedFirstPass ? 0 : child.getMeasuredHeight(); if (canSlide && child != mSlideableView) { if (lp.height < 0 && (measuredHeight > fixedPanelHeightLimit || lp.weight > 0)) { // Fixed panels in a sliding configuration should // be clamped to the fixed panel limit. final int childWidthSpec; if (skippedFirstPass) { // Do initial width measurement if we skipped measuring this view // the first time around. if (lp.width == LayoutParams.WRAP_CONTENT) { childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.AT_MOST); } else if (lp.height == LayoutParams.MATCH_PARENT) { childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.EXACTLY); } else { childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); } } else { childWidthSpec = MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY); } final int childHeightSpec = MeasureSpec.makeMeasureSpec(fixedPanelHeightLimit, MeasureSpec.EXACTLY); child.measure(childWidthSpec, childHeightSpec); } } else if (lp.weight > 0) { int childWidthSpec; if (lp.height == 0) { // This was skipped the first time; figure out a real width spec. if (lp.width == LayoutParams.WRAP_CONTENT) { childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.AT_MOST); } else if (lp.width == LayoutParams.MATCH_PARENT) { childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.EXACTLY); } else { childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); } } else { childWidthSpec = MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY); } if (canSlide) { // Consume available space final int verticalMargin = lp.topMargin + lp.bottomMargin; final int newHeight = heightAvailable - verticalMargin; final int childHeightSpec = MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY); if (measuredHeight != newHeight) { child.measure(childWidthSpec, childHeightSpec); } } else { // Distribute the extra width proportionally similar to LinearLayout final int heightToDistribute = Math.max(0, heightRemaining); final int addedHeight = (int) (lp.weight * heightToDistribute / weightSum); final int childHeightSpec = MeasureSpec.makeMeasureSpec(measuredHeight + addedHeight, MeasureSpec.EXACTLY); child.measure(childWidthSpec, childHeightSpec); } } } } final int measuredHeight = heightSize; final int measuredWidth = layoutWidth + getPaddingLeft() + getPaddingRight(); 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:com.example.newviewsplayground.WrappingSlidingPaneLayout.java
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int widthMode = MeasureSpec.getMode(widthMeasureSpec); final int widthSize = MeasureSpec.getSize(widthMeasureSpec); final int heightMode = MeasureSpec.getMode(heightMeasureSpec); final int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (widthMode != MeasureSpec.EXACTLY) { throw new IllegalStateException("Width must have an exact value or MATCH_PARENT"); } else if (heightMode == MeasureSpec.UNSPECIFIED) { throw new IllegalStateException("Height must not be UNSPECIFIED"); }// w ww . jav a 2 s . c o m 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; } float weightSum = 0; boolean canSlide = false; int widthRemaining = widthSize - getPaddingLeft() - getPaddingRight(); 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(widthSize - horizontalMargin, MeasureSpec.AT_MOST); } else if (lp.width == LayoutParams.FILL_PARENT) { childWidthSpec = MeasureSpec.makeMeasureSpec(widthSize - 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.FILL_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 = widthSize - mOverhangSize; for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); if (child.getVisibility() == GONE) { continue; } final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 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.FILL_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.FILL_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 = widthSize - 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); } } } } setMeasuredDimension(widthSize, layoutHeight); mCanSlide = canSlide; if (mDragHelper.getViewDragState() != ViewDragHelper.STATE_IDLE && !canSlide) { // Cancel scrolling in progress, it's no longer relevant. mDragHelper.abort(); } }
From source file:chao.widget.tablayout.TabLayout.java
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // If we have a MeasureSpec which allows us to decide our height, try and use the default // height// w w w. j a v a 2 s. c o m // final int idealHeight = dpToPx(getDefaultHeight()) + getPaddingTop() + getPaddingBottom(); // switch (MeasureSpec.getMode(heightMeasureSpec)) { // case MeasureSpec.AT_MOST: // heightMeasureSpec = MeasureSpec.makeMeasureSpec( // Math.min(idealHeight, MeasureSpec.getSize(heightMeasureSpec)), // MeasureSpec.EXACTLY); // break; // case MeasureSpec.UNSPECIFIED: // heightMeasureSpec = MeasureSpec.makeMeasureSpec(idealHeight, MeasureSpec.EXACTLY); // break; // } final int specWidth = MeasureSpec.getSize(widthMeasureSpec); if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) { // If we don't have an unspecified width spec, use the given size to calculate // the max tab width mTabMaxWidth = mRequestedTabMaxWidth > 0 ? mRequestedTabMaxWidth : specWidth - dpToPx(TAB_MIN_WIDTH_MARGIN); } // Now super measure itself using the (possibly) modified height spec super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (getChildCount() == 1) { // If we're in fixed mode then we need to make the tab strip is the same width as us // so we don't scroll final View child = getChildAt(0); boolean remeasure = false; switch (mMode) { case MODE_SCROLLABLE: // We only need to resize the child if it's smaller than us. This is similar // to fillViewport remeasure = child.getMeasuredWidth() < getMeasuredWidth(); break; case MODE_FIXED: case MODE_FIXED_COMMON: // Resize the child so that it doesn't scroll remeasure = child.getMeasuredWidth() != getMeasuredWidth(); break; } if (remeasure) { // Re-measure the child with a widthSpec set to be exactly our measure width int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom(), child.getLayoutParams().height); int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY); child.measure(childWidthMeasureSpec, childHeightMeasureSpec); } } }