/// <summary> /// Helper for makeAndAddView to set the position of a view /// and fill out its layout paramters. /// </summary> /// <remarks> /// Helper for makeAndAddView to set the position of a view /// and fill out its layout paramters. /// </remarks> /// <param name="child">The view to position</param> private void setUpChild(android.view.View child) { // Respect layout params that are already in the view. Otherwise // make some up... android.view.ViewGroup.LayoutParams lp = child.getLayoutParams(); if (lp == null) { lp = generateDefaultLayoutParams(); } addViewInLayout(child, 0, lp); child.setSelected(hasFocus()); // Get measure specs int childHeightSpec = android.view.ViewGroup.getChildMeasureSpec(mHeightMeasureSpec , mSpinnerPadding.top + mSpinnerPadding.bottom, lp.height); int childWidthSpec = android.view.ViewGroup.getChildMeasureSpec(mWidthMeasureSpec , mSpinnerPadding.left + mSpinnerPadding.right, lp.width); // Measure child child.measure(childWidthSpec, childHeightSpec); int childLeft; int childRight; // Position vertically based on gravity setting int childTop = mSpinnerPadding.top + ((getMeasuredHeight() - mSpinnerPadding.bottom - mSpinnerPadding.top - child.getMeasuredHeight()) / 2); int childBottom = childTop + child.getMeasuredHeight(); int width = child.getMeasuredWidth(); childLeft = 0; childRight = childLeft + width; child.layout(childLeft, childTop, childRight, childBottom); }
internal override int getChildrenSkipCount(android.view.View child, int index) { android.widget.TableRow.LayoutParams layoutParams = (android.widget.TableRow.LayoutParams )child.getLayoutParams(); // when the span is 1 (default), we need to skip 0 child return(layoutParams.span - 1); }
private void mapIndexAndColumns() { if (mColumnToChildIndex == null) { int virtualCount = 0; int count = getChildCount(); mColumnToChildIndex = new android.util.SparseIntArray(); android.util.SparseIntArray columnToChild = mColumnToChildIndex; { for (int i = 0; i < count; i++) { android.view.View child = getChildAt(i); android.widget.TableRow.LayoutParams layoutParams = (android.widget.TableRow.LayoutParams )child.getLayoutParams(); if (layoutParams.column >= virtualCount) { virtualCount = layoutParams.column; } { for (int j = 0; j < layoutParams.span; j++) { columnToChild.put(virtualCount++, i); } } } } mNumColumns = virtualCount; } }
/// <summary><p>Measures the preferred width of each child, including its margins.</p> /// </summary> /// <param name="widthMeasureSpec">the width constraint imposed by our parent</param> /// <returns> /// an array of integers corresponding to the width of each cell, or /// column, in this row /// <hide></hide> /// </returns> internal virtual int[] getColumnsWidths(int widthMeasureSpec) { int numColumns = getVirtualChildCount(); if (mColumnWidths == null || numColumns != mColumnWidths.Length) { mColumnWidths = new int[numColumns]; } int[] columnWidths = mColumnWidths; { for (int i = 0; i < numColumns; i++) { android.view.View child = getVirtualChildAt(i); if (child != null && child.getVisibility() != GONE) { android.widget.TableRow.LayoutParams layoutParams = (android.widget.TableRow.LayoutParams )child.getLayoutParams(); if (layoutParams.span == 1) { int spec; switch (layoutParams.width) { case android.view.ViewGroup.LayoutParams.WRAP_CONTENT: { spec = getChildMeasureSpec(widthMeasureSpec, 0, android.view.ViewGroup.LayoutParams .WRAP_CONTENT); break; } case android.view.ViewGroup.LayoutParams.MATCH_PARENT: { spec = android.view.View.MeasureSpec.makeMeasureSpec(0, android.view.View.MeasureSpec .UNSPECIFIED); break; } default: { spec = android.view.View.MeasureSpec.makeMeasureSpec(layoutParams.width, android.view.View .MeasureSpec.EXACTLY); break; } } child.measure(spec, spec); int width = child.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin; columnWidths[i] = width; } else { columnWidths[i] = 0; } } else { columnWidths[i] = 0; } } } return(columnWidths); }
protected internal override long getDelayForView(android.view.View view) { android.view.ViewGroup.LayoutParams lp = view.getLayoutParams(); android.view.animation.GridLayoutAnimationController.AnimationParameters @params = (android.view.animation.GridLayoutAnimationController.AnimationParameters)lp.layoutAnimationParameters; if (@params == null) { return(0); } int column = getTransformedColumnIndex(@params); int row = getTransformedRowIndex(@params); int rowsCount = @params.rowsCount; int columnsCount = @params.columnsCount; long duration = mAnimation.getDuration(); float columnDelay = mColumnDelay * duration; float rowDelay = mRowDelay * duration; float totalDelay; long viewDelay; if (mInterpolator == null) { mInterpolator = new android.view.animation.LinearInterpolator(); } switch (mDirectionPriority) { case PRIORITY_COLUMN: { viewDelay = (long)(row * rowDelay + column * rowsCount * rowDelay); totalDelay = rowsCount * rowDelay + columnsCount * rowsCount * rowDelay; break; } case PRIORITY_ROW: { viewDelay = (long)(column * columnDelay + row * columnsCount * columnDelay); totalDelay = columnsCount * columnDelay + rowsCount * columnsCount * columnDelay; break; } case PRIORITY_NONE: default: { viewDelay = (long)(column * columnDelay + row * rowDelay); totalDelay = columnsCount * columnDelay + rowsCount * rowDelay; break; } } float normalizedDelay = viewDelay / totalDelay; normalizedDelay = mInterpolator.getInterpolation(normalizedDelay); return((long)(normalizedDelay * totalDelay)); }
private android.view.View obtainView() { android.view.View child = mFactory.makeView(); android.widget.FrameLayout.LayoutParams lp = (android.widget.FrameLayout.LayoutParams )child.getLayoutParams(); if (lp == null) { lp = new android.widget.FrameLayout.LayoutParams(android.view.ViewGroup.LayoutParams .MATCH_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT); } addView(child, lp); return(child); }
internal virtual int measureContentWidth(android.widget.SpinnerAdapter adapter, android.graphics.drawable.Drawable background) { if (adapter == null) { return(0); } int width = 0; android.view.View itemView = null; int itemType = 0; int widthMeasureSpec = android.view.View.MeasureSpec.makeMeasureSpec(0, android.view.View .MeasureSpec.UNSPECIFIED); int heightMeasureSpec = android.view.View.MeasureSpec.makeMeasureSpec(0, android.view.View .MeasureSpec.UNSPECIFIED); // Make sure the number of items we'll measure is capped. If it's a huge data set // with wildly varying sizes, oh well. int start = System.Math.Max(0, getSelectedItemPosition()); int end = System.Math.Min(adapter.getCount(), start + MAX_ITEMS_MEASURED); int count = end - start; start = System.Math.Max(0, start - (MAX_ITEMS_MEASURED - count)); { for (int i = start; i < end; i++) { int positionType = adapter.getItemViewType(i); if (positionType != itemType) { itemType = positionType; itemView = null; } itemView = adapter.getView(i, itemView, this); if (itemView.getLayoutParams() == null) { itemView.setLayoutParams(new android.view.ViewGroup.LayoutParams(android.view.ViewGroup .LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT)); } itemView.measure(widthMeasureSpec, heightMeasureSpec); width = System.Math.Max(width, itemView.getMeasuredWidth()); } } // Add background padding to measured width if (background != null) { background.getPadding(mTempRect); width += mTempRect.left + mTempRect.right; } return(width); }
public override void addView(android.view.View child) { if (child.getLayoutParams() == null) { android.widget.LinearLayout.LayoutParams lp = new android.widget.LinearLayout.LayoutParams (0, android.view.ViewGroup.LayoutParams.MATCH_PARENT, 1.0f); lp.setMargins(0, 0, 0, 0); child.setLayoutParams(lp); } // Ensure you can navigate to the tab with the keyboard, and you can touch it child.setFocusable(true); child.setClickable(true); base.addView(child); // TODO: detect this via geometry with a tabwidget listener rather // than potentially interfere with the view's listener child.setOnClickListener(new android.widget.TabWidget.TabClickListener(this, getTabCount () - 1)); child.setOnFocusChangeListener(this); }
protected internal override void onLayout(bool changed, int l, int t, int r, int b) { int count = getChildCount(); { for (int i = 0; i < count; i++) { android.view.View child = getChildAt(i); if (child.getVisibility() != GONE) { android.widget.AbsoluteLayout.LayoutParams lp = (android.widget.AbsoluteLayout.LayoutParams )child.getLayoutParams(); int childLeft = mPaddingLeft + lp.x; int childTop = mPaddingTop + lp.y; child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } }
/// <summary> /// Returns the amount of milliseconds by which the specified view's /// animation must be delayed or offset. /// </summary> /// <remarks> /// Returns the amount of milliseconds by which the specified view's /// animation must be delayed or offset. Subclasses should override this /// method to return a suitable value. /// This implementation returns <code>child animation delay</code> /// milliseconds where: /// <pre> /// child animation delay = child index * delay /// </pre> /// The index is retrieved from the /// <see cref="AnimationParameters">AnimationParameters</see> /// found in the view's /// <see cref="android.view.ViewGroup.LayoutParams">android.view.ViewGroup.LayoutParams /// </see> /// . /// </remarks> /// <param name="view">the view for which to obtain the animation's delay</param> /// <returns>a delay in milliseconds</returns> /// <seealso cref="getAnimationForView(android.view.View)">getAnimationForView(android.view.View) /// </seealso> /// <seealso cref="getDelay()">getDelay()</seealso> /// <seealso cref="getTransformedIndex(AnimationParameters)">getTransformedIndex(AnimationParameters) /// </seealso> /// <seealso cref="android.view.ViewGroup.LayoutParams">android.view.ViewGroup.LayoutParams /// </seealso> protected internal virtual long getDelayForView(android.view.View view) { android.view.ViewGroup.LayoutParams lp = view.getLayoutParams(); android.view.animation.LayoutAnimationController.AnimationParameters @params = lp .layoutAnimationParameters; if (@params == null) { return(0); } float delay = mDelay * mAnimation.getDuration(); long viewDelay = (long)(getTransformedIndex(@params) * delay); float totalDelay = delay * @params.count; if (mInterpolator == null) { mInterpolator = new android.view.animation.LinearInterpolator(); } float normalizedDelay = viewDelay / totalDelay; normalizedDelay = mInterpolator.getInterpolation(normalizedDelay); return((long)(normalizedDelay * totalDelay)); }
protected internal override void onMeasure(int widthMeasureSpec, int heightMeasureSpec ) { int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; // Find out how big everyone wants to be measureChildren(widthMeasureSpec, heightMeasureSpec); { // Find rightmost and bottom-most child for (int i = 0; i < count; i++) { android.view.View child = getChildAt(i); if (child.getVisibility() != GONE) { int childRight; int childBottom; android.widget.AbsoluteLayout.LayoutParams lp = (android.widget.AbsoluteLayout.LayoutParams )child.getLayoutParams(); childRight = lp.x + child.getMeasuredWidth(); childBottom = lp.y + child.getMeasuredHeight(); maxWidth = System.Math.Max(maxWidth, childRight); maxHeight = System.Math.Max(maxHeight, childBottom); } } } // Account for padding too maxWidth += mPaddingLeft + mPaddingRight; maxHeight += mPaddingTop + mPaddingBottom; // Check against minimum height and width maxHeight = System.Math.Max(maxHeight, getSuggestedMinimumHeight()); maxWidth = System.Math.Max(maxWidth, getSuggestedMinimumWidth()); setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0), resolveSizeAndState (maxHeight, heightMeasureSpec, 0)); }
public override android.view.View getItemView([email protected] item, android.view.View convertView, android.view.ViewGroup parent) { android.view.View actionView = item.getActionView(); if (actionView == null || item.hasCollapsibleActionView()) { if (!(convertView is [email protected])) { convertView = null; } actionView = base.getItemView(item, convertView, parent); } actionView.setVisibility(item.isActionViewExpanded() ? android.view.View.GONE : android.view.View .VISIBLE); [email protected] menuParent = ([email protected] )parent; android.view.ViewGroup.LayoutParams lp = actionView.getLayoutParams(); if (!menuParent.checkLayoutParams(lp)) { actionView.setLayoutParams((([email protected] )menuParent.generateLayoutParams(lp))); } return(actionView); }
protected internal override void onLayout(bool changed, int left, int top, int right , int bottom) { if (!mFormatItems) { base.onLayout(changed, left, top, right, bottom); return; } int childCount = getChildCount(); int midVertical = (top + bottom) / 2; int dividerWidth = getDividerWidth(); int overflowWidth = 0; int nonOverflowWidth = 0; int nonOverflowCount = 0; int widthRemaining = right - left - getPaddingRight() - getPaddingLeft(); bool hasOverflow = false; { for (int i = 0; i < childCount; i++) { android.view.View v = getChildAt(i); if (v.getVisibility() == GONE) { continue; } [email protected] p = ([email protected] .LayoutParams)v.getLayoutParams(); if (p.isOverflowButton) { overflowWidth = v.getMeasuredWidth(); if (hasDividerBeforeChildAt(i)) { overflowWidth += dividerWidth; } int height = v.getMeasuredHeight(); int r = getWidth() - getPaddingRight() - p.rightMargin; int l = r - overflowWidth; int t = midVertical - (height / 2); int b = t + height; v.layout(l, t, r, b); widthRemaining -= overflowWidth; hasOverflow = true; } else { int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin; nonOverflowWidth += size; widthRemaining -= size; if (hasDividerBeforeChildAt(i)) { nonOverflowWidth += dividerWidth; } nonOverflowCount++; } } } if (childCount == 1 && !hasOverflow) { // Center a single child android.view.View v = getChildAt(0); int width = v.getMeasuredWidth(); int height = v.getMeasuredHeight(); int midHorizontal = (right - left) / 2; int l = midHorizontal - width / 2; int t = midVertical - height / 2; v.layout(l, t, l + width, t + height); return; } int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1); int spacerSize = System.Math.Max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0); int startLeft = getPaddingLeft(); { for (int i_1 = 0; i_1 < childCount; i_1++) { android.view.View v = getChildAt(i_1); [email protected] lp = ([email protected] .LayoutParams)v.getLayoutParams(); if (v.getVisibility() == GONE || lp.isOverflowButton) { continue; } startLeft += lp.leftMargin; int width = v.getMeasuredWidth(); int height = v.getMeasuredHeight(); int t = midVertical - height / 2; v.layout(startLeft, t, startLeft + width, t + height); startLeft += width + lp.rightMargin + spacerSize; } } }
/// <summary>Measure a child view to fit within cell-based formatting.</summary> /// <remarks> /// Measure a child view to fit within cell-based formatting. The child's width /// will be measured to a whole multiple of cellSize. /// <p>Sets the expandable and cellsUsed fields of LayoutParams. /// </remarks> /// <param name="child">Child to measure</param> /// <param name="cellSize">Size of one cell</param> /// <param name="cellsRemaining">Number of cells remaining that this view can expand to fill /// </param> /// <param name="parentHeightMeasureSpec">MeasureSpec used by the parent view</param> /// <param name="parentHeightPadding">Padding present in the parent view</param> /// <returns>Number of cells this child was measured to occupy</returns> internal static int measureChildForCells(android.view.View child, int cellSize, int cellsRemaining, int parentHeightMeasureSpec, int parentHeightPadding) { [email protected] lp = ([email protected] .LayoutParams)child.getLayoutParams(); int childHeightSize = android.view.View.MeasureSpec.getSize(parentHeightMeasureSpec ) - parentHeightPadding; int childHeightMode = android.view.View.MeasureSpec.getMode(parentHeightMeasureSpec ); int childHeightSpec = android.view.View.MeasureSpec.makeMeasureSpec(childHeightSize , childHeightMode); int cellsUsed = 0; if (cellsRemaining > 0) { int childWidthSpec = android.view.View.MeasureSpec.makeMeasureSpec(cellSize * cellsRemaining , android.view.View.MeasureSpec.AT_MOST); child.measure(childWidthSpec, childHeightSpec); int measuredWidth = child.getMeasuredWidth(); cellsUsed = measuredWidth / cellSize; if (measuredWidth % cellSize != 0) { cellsUsed++; } } [email protected] itemView = child is [email protected] ? ([email protected])child : null; bool expandable = !lp.isOverflowButton && itemView != null && itemView.hasText(); lp.expandable = expandable; lp.cellsUsed = cellsUsed; int targetWidth = cellsUsed * cellSize; child.measure(android.view.View.MeasureSpec.makeMeasureSpec(targetWidth, android.view.View .MeasureSpec.EXACTLY), childHeightSpec); return(cellsUsed); }
private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) { // We already know the width mode is EXACTLY if we're here. int heightMode = android.view.View.MeasureSpec.getMode(heightMeasureSpec); int widthSize = android.view.View.MeasureSpec.getSize(widthMeasureSpec); int heightSize = android.view.View.MeasureSpec.getSize(heightMeasureSpec); int widthPadding = getPaddingLeft() + getPaddingRight(); int heightPadding = getPaddingTop() + getPaddingBottom(); widthSize -= widthPadding; // Divide the view into cells. int cellCount = widthSize / mMinCellSize; int cellSizeRemaining = widthSize % mMinCellSize; if (cellCount == 0) { // Give up, nothing fits. setMeasuredDimension(widthSize, 0); return; } int cellSize = mMinCellSize + cellSizeRemaining / cellCount; int cellsRemaining = cellCount; int maxChildHeight = 0; int maxCellsUsed = 0; int expandableItemCount = 0; int visibleItemCount = 0; bool hasOverflow = false; // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64. long smallestItemsAt = 0; int childCount = getChildCount(); { for (int i = 0; i < childCount; i++) { android.view.View child = getChildAt(i); if (child.getVisibility() == GONE) { continue; } bool isGeneratedItem = child is [email protected]; visibleItemCount++; if (isGeneratedItem) { // Reset padding for generated menu item views; it may change below // and views are recycled. child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0); } [email protected] lp = ([email protected] .LayoutParams)child.getLayoutParams(); lp.expanded = false; lp.extraPixels = 0; lp.cellsUsed = 0; lp.expandable = false; lp.leftMargin = 0; lp.rightMargin = 0; lp.preventEdgeOffset = isGeneratedItem && (([email protected] )child).hasText(); // Overflow always gets 1 cell. No more, no less. int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining; int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable, heightMeasureSpec , heightPadding); maxCellsUsed = System.Math.Max(maxCellsUsed, cellsUsed); if (lp.expandable) { expandableItemCount++; } if (lp.isOverflowButton) { hasOverflow = true; } cellsRemaining -= cellsUsed; maxChildHeight = System.Math.Max(maxChildHeight, child.getMeasuredHeight()); if (cellsUsed == 1) { smallestItemsAt |= (1 << i); } } } // When we have overflow and a single expanded (text) item, we want to try centering it // visually in the available space even though overflow consumes some of it. bool centerSingleExpandedItem = hasOverflow && visibleItemCount == 2; // Divide space for remaining cells if we have items that can expand. // Try distributing whole leftover cells to smaller items first. bool needsExpansion = false; while (expandableItemCount > 0 && cellsRemaining > 0) { int minCells = int.MaxValue; long minCellsAt = 0; // Bit locations are indices of relevant child views int minCellsItemCount = 0; { for (int i_1 = 0; i_1 < childCount; i_1++) { android.view.View child = getChildAt(i_1); [email protected] lp = ([email protected] .LayoutParams)child.getLayoutParams(); // Don't try to expand items that shouldn't. if (!lp.expandable) { continue; } // Mark indices of children that can receive an extra cell. if (lp.cellsUsed < minCells) { minCells = lp.cellsUsed; minCellsAt = 1 << i_1; minCellsItemCount = 1; } else { if (lp.cellsUsed == minCells) { minCellsAt |= 1 << i_1; minCellsItemCount++; } } } } // Items that get expanded will always be in the set of smallest items when we're done. smallestItemsAt |= minCellsAt; if (minCellsItemCount > cellsRemaining) { break; } // Couldn't expand anything evenly. Stop. // We have enough cells, all minimum size items will be incremented. minCells++; { for (int i_2 = 0; i_2 < childCount; i_2++) { android.view.View child = getChildAt(i_2); [email protected] lp = ([email protected] .LayoutParams)child.getLayoutParams(); if ((minCellsAt & (1 << i_2)) == 0) { // If this item is already at our small item count, mark it for later. if (lp.cellsUsed == minCells) { smallestItemsAt |= 1 << i_2; } continue; } if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) { // Add padding to this item such that it centers. child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0); } lp.cellsUsed++; lp.expanded = true; cellsRemaining--; } } needsExpansion = true; } // Divide any space left that wouldn't divide along cell boundaries // evenly among the smallest items bool singleItem = !hasOverflow && visibleItemCount == 1; if (cellsRemaining > 0 && smallestItemsAt != 0 && (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) { float expandCount = Sharpen.Util.Long_GetBitCount(smallestItemsAt); if (!singleItem) { // The items at the far edges may only expand by half in order to pin to either side. if ((smallestItemsAt & 1) != 0) { [email protected] lp = ([email protected] .LayoutParams)getChildAt(0).getLayoutParams(); if (!lp.preventEdgeOffset) { expandCount -= 0.5f; } } if ((smallestItemsAt & (1 << (childCount - 1))) != 0) { [email protected] lp = (([email protected] .LayoutParams)getChildAt(childCount - 1).getLayoutParams()); if (!lp.preventEdgeOffset) { expandCount -= 0.5f; } } } int extraPixels = expandCount > 0 ? (int)(cellsRemaining * cellSize / expandCount ) : 0; { for (int i_1 = 0; i_1 < childCount; i_1++) { if ((smallestItemsAt & (1 << i_1)) == 0) { continue; } android.view.View child = getChildAt(i_1); [email protected] lp = ([email protected] .LayoutParams)child.getLayoutParams(); if (child is [email protected]) { // If this is one of our views, expand and measure at the larger size. lp.extraPixels = extraPixels; lp.expanded = true; if (i_1 == 0 && !lp.preventEdgeOffset) { // First item gets part of its new padding pushed out of sight. // The last item will get this implicitly from layout. lp.leftMargin = -extraPixels / 2; } needsExpansion = true; } else { if (lp.isOverflowButton) { lp.extraPixels = extraPixels; lp.expanded = true; lp.rightMargin = -extraPixels / 2; needsExpansion = true; } else { // If we don't know what it is, give it some margins instead // and let it center within its space. We still want to pin // against the edges. if (i_1 != 0) { lp.leftMargin = extraPixels / 2; } if (i_1 != childCount - 1) { lp.rightMargin = extraPixels / 2; } } } } } cellsRemaining = 0; } // Remeasure any items that have had extra space allocated to them. if (needsExpansion) { int heightSpec = android.view.View.MeasureSpec.makeMeasureSpec(heightSize - heightPadding , heightMode); { for (int i_1 = 0; i_1 < childCount; i_1++) { android.view.View child = getChildAt(i_1); [email protected] lp = ([email protected] .LayoutParams)child.getLayoutParams(); if (!lp.expanded) { continue; } int width = lp.cellsUsed * cellSize + lp.extraPixels; child.measure(android.view.View.MeasureSpec.makeMeasureSpec(width, android.view.View .MeasureSpec.EXACTLY), heightSpec); } } } if (heightMode != android.view.View.MeasureSpec.EXACTLY) { heightSize = maxChildHeight; } setMeasuredDimension(widthSize, heightSize); mMeasuredExtraWidth = cellsRemaining * cellSize; }
protected internal override void onMeasure(int widthMeasureSpec, int heightMeasureSpec ) { int widthMode = android.view.View.MeasureSpec.getMode(widthMeasureSpec); if (widthMode != android.view.View.MeasureSpec.EXACTLY) { throw new System.InvalidOperationException(GetType().Name + " can only be used " + "with android:layout_width=\"match_parent\" (or fill_parent)"); } int heightMode = android.view.View.MeasureSpec.getMode(heightMeasureSpec); if (heightMode == android.view.View.MeasureSpec.UNSPECIFIED) { throw new System.InvalidOperationException(GetType().Name + " can only be used " + "with android:layout_height=\"wrap_content\""); } int contentWidth = android.view.View.MeasureSpec.getSize(widthMeasureSpec); int maxHeight = mContentHeight > 0 ? mContentHeight : android.view.View.MeasureSpec .getSize(heightMeasureSpec); int verticalPadding = getPaddingTop() + getPaddingBottom(); int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight(); int height = maxHeight - verticalPadding; int childSpecHeight = android.view.View.MeasureSpec.makeMeasureSpec(height, android.view.View .MeasureSpec.AT_MOST); if (mClose != null) { availableWidth = measureChildView(mClose, availableWidth, childSpecHeight, 0); android.view.ViewGroup.MarginLayoutParams lp = (android.view.ViewGroup.MarginLayoutParams )mClose.getLayoutParams(); availableWidth -= lp.leftMargin + lp.rightMargin; } if (mMenuView != null && mMenuView.getParent() == this) { availableWidth = measureChildView(mMenuView, availableWidth, childSpecHeight, 0); } if (mTitleLayout != null && mCustomView == null) { availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); } if (mCustomView != null) { android.view.ViewGroup.LayoutParams lp = mCustomView.getLayoutParams(); int customWidthMode = lp.width != android.view.ViewGroup.LayoutParams.WRAP_CONTENT ? android.view.View.MeasureSpec.EXACTLY : android.view.View.MeasureSpec.AT_MOST; int customWidth = lp.width >= 0 ? System.Math.Min(lp.width, availableWidth) : availableWidth; int customHeightMode = lp.height != android.view.ViewGroup.LayoutParams.WRAP_CONTENT ? android.view.View.MeasureSpec.EXACTLY : android.view.View.MeasureSpec.AT_MOST; int customHeight = lp.height >= 0 ? System.Math.Min(lp.height, height) : height; mCustomView.measure(android.view.View.MeasureSpec.makeMeasureSpec(customWidth, customWidthMode ), android.view.View.MeasureSpec.makeMeasureSpec(customHeight, customHeightMode) ); } if (mContentHeight <= 0) { int measuredHeight = 0; int count = getChildCount(); { for (int i = 0; i < count; i++) { android.view.View v = getChildAt(i); int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; if (paddedViewHeight > measuredHeight) { measuredHeight = paddedViewHeight; } } } setMeasuredDimension(contentWidth, measuredHeight); } else { setMeasuredDimension(contentWidth, maxHeight); } }
protected internal override void onMeasure(int widthMeasureSpec, int heightMeasureSpec ) { int widthMode = android.view.View.MeasureSpec.getMode(widthMeasureSpec); int widthSize; int heightSize; mSpinnerPadding.left = mPaddingLeft > mSelectionLeftPadding ? mPaddingLeft : mSelectionLeftPadding; mSpinnerPadding.top = mPaddingTop > mSelectionTopPadding ? mPaddingTop : mSelectionTopPadding; mSpinnerPadding.right = mPaddingRight > mSelectionRightPadding ? mPaddingRight : mSelectionRightPadding; mSpinnerPadding.bottom = mPaddingBottom > mSelectionBottomPadding ? mPaddingBottom : mSelectionBottomPadding; if (mDataChanged) { handleDataChanged(); } int preferredHeight = 0; int preferredWidth = 0; bool needsMeasuring = true; int selectedPosition = getSelectedItemPosition(); if (selectedPosition >= 0 && mAdapter != null && selectedPosition < mAdapter.getCount ()) { // Try looking in the recycler. (Maybe we were measured once already) android.view.View view = mRecycler.get(selectedPosition); if (view == null) { // Make a new one view = mAdapter.getView(selectedPosition, null, this); } if (view != null) { // Put in recycler for re-measuring and/or layout mRecycler.put(selectedPosition, view); } if (view != null) { if (view.getLayoutParams() == null) { mBlockLayoutRequests = true; view.setLayoutParams(generateDefaultLayoutParams()); mBlockLayoutRequests = false; } measureChild(view, widthMeasureSpec, heightMeasureSpec); preferredHeight = getChildHeight(view) + mSpinnerPadding.top + mSpinnerPadding.bottom; preferredWidth = getChildWidth(view) + mSpinnerPadding.left + mSpinnerPadding.right; needsMeasuring = false; } } if (needsMeasuring) { // No views -- just use padding preferredHeight = mSpinnerPadding.top + mSpinnerPadding.bottom; if (widthMode == android.view.View.MeasureSpec.UNSPECIFIED) { preferredWidth = mSpinnerPadding.left + mSpinnerPadding.right; } } preferredHeight = System.Math.Max(preferredHeight, getSuggestedMinimumHeight()); preferredWidth = System.Math.Max(preferredWidth, getSuggestedMinimumWidth()); heightSize = resolveSizeAndState(preferredHeight, heightMeasureSpec, 0); widthSize = resolveSizeAndState(preferredWidth, widthMeasureSpec, 0); setMeasuredDimension(widthSize, heightSize); mHeightMeasureSpec = heightMeasureSpec; mWidthMeasureSpec = widthMeasureSpec; }
protected internal override void onMeasure(int widthMeasureSpec, int heightMeasureSpec ) { int count = getChildCount(); bool measureMatchParentChildren = android.view.View.MeasureSpec.getMode(widthMeasureSpec ) != android.view.View.MeasureSpec.EXACTLY || android.view.View.MeasureSpec.getMode (heightMeasureSpec) != android.view.View.MeasureSpec.EXACTLY; mMatchParentChildren.clear(); int maxHeight = 0; int maxWidth = 0; int childState = 0; { for (int i = 0; i < count; i++) { android.view.View child = getChildAt(i); if (mMeasureAllChildren || child.getVisibility() != GONE) { measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); android.widget.FrameLayout.LayoutParams lp = (android.widget.FrameLayout.LayoutParams )child.getLayoutParams(); maxWidth = System.Math.Max(maxWidth, child.getMeasuredWidth() + lp.leftMargin + lp .rightMargin); maxHeight = System.Math.Max(maxHeight, child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); childState = combineMeasuredStates(childState, child.getMeasuredState()); if (measureMatchParentChildren) { if (lp.width == android.view.ViewGroup.LayoutParams.MATCH_PARENT || lp.height == android.view.ViewGroup.LayoutParams.MATCH_PARENT) { mMatchParentChildren.add(child); } } } } } // Account for padding too maxWidth += getPaddingLeftWithForeground() + getPaddingRightWithForeground(); maxHeight += getPaddingTopWithForeground() + getPaddingBottomWithForeground(); // Check against our minimum height and width maxHeight = System.Math.Max(maxHeight, getSuggestedMinimumHeight()); maxWidth = System.Math.Max(maxWidth, getSuggestedMinimumWidth()); // Check against our foreground's minimum height and width android.graphics.drawable.Drawable drawable = getForeground(); if (drawable != null) { maxHeight = System.Math.Max(maxHeight, drawable.getMinimumHeight()); maxWidth = System.Math.Max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState), resolveSizeAndState(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT )); count = mMatchParentChildren.size(); if (count > 1) { { for (int i_1 = 0; i_1 < count; i_1++) { android.view.View child = mMatchParentChildren.get(i_1); android.view.ViewGroup.MarginLayoutParams lp = (android.view.ViewGroup.MarginLayoutParams )child.getLayoutParams(); int childWidthMeasureSpec; int childHeightMeasureSpec; if (lp.width == android.view.ViewGroup.LayoutParams.MATCH_PARENT) { childWidthMeasureSpec = android.view.View.MeasureSpec.makeMeasureSpec(getMeasuredWidth () - getPaddingLeftWithForeground() - getPaddingRightWithForeground() - lp.leftMargin - lp.rightMargin, android.view.View.MeasureSpec.EXACTLY); } else { childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, getPaddingLeftWithForeground () + getPaddingRightWithForeground() + lp.leftMargin + lp.rightMargin, lp.width); } if (lp.height == android.view.ViewGroup.LayoutParams.MATCH_PARENT) { childHeightMeasureSpec = android.view.View.MeasureSpec.makeMeasureSpec(getMeasuredHeight () - getPaddingTopWithForeground() - getPaddingBottomWithForeground() - lp.topMargin - lp.bottomMargin, android.view.View.MeasureSpec.EXACTLY); } else { childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, getPaddingTopWithForeground () + getPaddingBottomWithForeground() + lp.topMargin + lp.bottomMargin, lp.height ); } child.measure(childWidthMeasureSpec, childHeightMeasureSpec); } } } }
protected internal override void onLayout(bool changed, int left, int top, int right , int bottom) { int count = getChildCount(); int parentLeft = getPaddingLeftWithForeground(); int parentRight = right - left - getPaddingRightWithForeground(); int parentTop = getPaddingTopWithForeground(); int parentBottom = bottom - top - getPaddingBottomWithForeground(); mForegroundBoundsChanged = true; { for (int i = 0; i < count; i++) { android.view.View child = getChildAt(i); if (child.getVisibility() != GONE) { android.widget.FrameLayout.LayoutParams lp = (android.widget.FrameLayout.LayoutParams )child.getLayoutParams(); int width = child.getMeasuredWidth(); int height = child.getMeasuredHeight(); int childLeft; int childTop; int gravity = lp.gravity; if (gravity == -1) { gravity = DEFAULT_CHILD_GRAVITY; } int layoutDirection = getResolvedLayoutDirection(); int absoluteGravity = android.view.Gravity.getAbsoluteGravity(gravity, layoutDirection ); int verticalGravity = gravity & android.view.Gravity.VERTICAL_GRAVITY_MASK; switch (absoluteGravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) { case android.view.Gravity.LEFT: { childLeft = parentLeft + lp.leftMargin; break; } case android.view.Gravity.CENTER_HORIZONTAL: { childLeft = parentLeft + (parentRight - parentLeft - width) / 2 + lp.leftMargin - lp.rightMargin; break; } case android.view.Gravity.RIGHT: { childLeft = parentRight - width - lp.rightMargin; break; } default: { childLeft = parentLeft + lp.leftMargin; break; } } switch (verticalGravity) { case android.view.Gravity.TOP: { childTop = parentTop + lp.topMargin; break; } case android.view.Gravity.CENTER_VERTICAL: { childTop = parentTop + (parentBottom - parentTop - height) / 2 + lp.topMargin - lp .bottomMargin; break; } case android.view.Gravity.BOTTOM: { childTop = parentBottom - height - lp.bottomMargin; break; } default: { childTop = parentTop + lp.topMargin; break; } } child.layout(childLeft, childTop, childLeft + width, childTop + height); } } } }
internal override int getNextLocationOffset(android.view.View child) { return(((android.widget.TableRow.LayoutParams)child.getLayoutParams()).mOffset[android.widget.TableRow .LayoutParams.LOCATION_NEXT]); }
/// <summary> /// Checks whether each item's title is fully visible using the current /// layout. /// </summary> /// <remarks> /// Checks whether each item's title is fully visible using the current /// layout. /// </remarks> /// <returns> /// True if the items fit (each item's text is fully visible), false /// otherwise. /// </returns> private bool doItemsFit() { int itemPos = 0; int[] layout_1 = mLayout; int numRows = mLayoutNumRows; { for (int row = 0; row < numRows; row++) { int numItemsOnRow = layout_1[row]; if (numItemsOnRow == 1) { itemPos++; continue; } { for (int itemsOnRowCounter = numItemsOnRow; itemsOnRowCounter > 0; itemsOnRowCounter --) { android.view.View child = getChildAt(itemPos++); [email protected] lp = ([email protected] .LayoutParams)child.getLayoutParams(); if (lp.maxNumItemsOnRow < numItemsOnRow) { return(false); } } } } } return(true); }
internal override void measureChildBeforeLayout(android.view.View child, int childIndex , int widthMeasureSpec, int totalWidth, int heightMeasureSpec, int totalHeight) { if (mConstrainedColumnWidths != null) { android.widget.TableRow.LayoutParams lp = (android.widget.TableRow.LayoutParams)child .getLayoutParams(); int measureMode = android.view.View.MeasureSpec.EXACTLY; int columnWidth = 0; int span = lp.span; int[] constrainedColumnWidths = mConstrainedColumnWidths; { for (int i = 0; i < span; i++) { columnWidth += constrainedColumnWidths[childIndex + i]; } } int gravity = lp.gravity; bool isHorizontalGravity = android.view.Gravity.isHorizontal(gravity); if (isHorizontalGravity) { measureMode = android.view.View.MeasureSpec.AT_MOST; } // no need to care about padding here, // ViewGroup.getChildMeasureSpec() would get rid of it anyway // because of the EXACTLY measure spec we use int childWidthMeasureSpec = android.view.View.MeasureSpec.makeMeasureSpec(System.Math.Max (0, columnWidth - lp.leftMargin - lp.rightMargin), measureMode); int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin + totalHeight, lp.height); child.measure(childWidthMeasureSpec, childHeightMeasureSpec); if (isHorizontalGravity) { int childWidth = child.getMeasuredWidth(); lp.mOffset[android.widget.TableRow.LayoutParams.LOCATION_NEXT] = columnWidth - childWidth; int layoutDirection = getResolvedLayoutDirection(); int absoluteGravity = android.view.Gravity.getAbsoluteGravity(gravity, layoutDirection ); switch (absoluteGravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) { case android.view.Gravity.LEFT: { // don't offset on X axis break; } case android.view.Gravity.RIGHT: { lp.mOffset[android.widget.TableRow.LayoutParams.LOCATION] = lp.mOffset[android.widget.TableRow .LayoutParams.LOCATION_NEXT]; break; } case android.view.Gravity.CENTER_HORIZONTAL: { lp.mOffset[android.widget.TableRow.LayoutParams.LOCATION] = lp.mOffset[android.widget.TableRow .LayoutParams.LOCATION_NEXT] / 2; break; } } } else { lp.mOffset[android.widget.TableRow.LayoutParams.LOCATION] = lp.mOffset[android.widget.TableRow .LayoutParams.LOCATION_NEXT] = 0; } } else { // fail silently when column widths are not available base.measureChildBeforeLayout(child, childIndex, widthMeasureSpec, totalWidth, heightMeasureSpec , totalHeight); } }