@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int x = getPaddingLeft(); final int y = getPaddingTop(); final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); if (contentHeight <= 0) { // Nothing to do if we can't see anything. return; } HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; if (homeLayout.getVisibility() != GONE) { final int leftOffset = homeLayout.getLeftOffset(); x += positionChild(homeLayout, x + leftOffset, y, contentHeight) + leftOffset; } if (mExpandedActionView == null) { final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; if (showTitle) { x += positionChild(mTitleLayout, x, y, contentHeight); } switch (mNavigationMode) { case ActionBar.NAVIGATION_MODE_STANDARD: break; case ActionBar.NAVIGATION_MODE_LIST: if (mListNavLayout != null) { if (showTitle) x += mItemPadding; x += positionChild(mListNavLayout, x, y, contentHeight) + mItemPadding; } break; case ActionBar.NAVIGATION_MODE_TABS: if (mTabScrollView != null) { if (showTitle) x += mItemPadding; x += positionChild(mTabScrollView, x, y, contentHeight) + mItemPadding; } break; } } int menuLeft = r - l - getPaddingRight(); if (mMenuView != null && mMenuView.getParent() == this) { positionChildInverse(mMenuView, menuLeft, y, contentHeight); menuLeft -= mMenuView.getMeasuredWidth(); } if (mIndeterminateProgressView != null && mIndeterminateProgressView.getVisibility() != GONE) { positionChildInverse(mIndeterminateProgressView, menuLeft, y, contentHeight); menuLeft -= mIndeterminateProgressView.getMeasuredWidth(); } View customView = null; if (mExpandedActionView != null) { customView = mExpandedActionView; } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { customView = mCustomNavView; } if (customView != null) { ViewGroup.LayoutParams lp = customView.getLayoutParams(); final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? (ActionBar.LayoutParams) lp : null; final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY; final int navWidth = customView.getMeasuredWidth(); int topMargin = 0; int bottomMargin = 0; if (ablp != null) { x += ablp.leftMargin; menuLeft -= ablp.rightMargin; topMargin = ablp.topMargin; bottomMargin = ablp.bottomMargin; } int hgravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; // See if we actually have room to truly center; if not push against left or right. if (hgravity == Gravity.CENTER_HORIZONTAL) { final int centeredLeft = ((getRight() - getLeft()) - navWidth) / 2; if (centeredLeft < x) { hgravity = Gravity.LEFT; } else if (centeredLeft + navWidth > menuLeft) { hgravity = Gravity.RIGHT; } } else if (gravity == -1) { hgravity = Gravity.LEFT; } int xpos = 0; switch (hgravity) { case Gravity.CENTER_HORIZONTAL: xpos = ((getRight() - getLeft()) - navWidth) / 2; break; case Gravity.LEFT: xpos = x; break; case Gravity.RIGHT: xpos = menuLeft - navWidth; break; } int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; if (gravity == -1) { vgravity = Gravity.CENTER_VERTICAL; } int ypos = 0; switch (vgravity) { case Gravity.CENTER_VERTICAL: final int paddedTop = getPaddingTop(); final int paddedBottom = getBottom() - getTop() - getPaddingBottom(); ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2; break; case Gravity.TOP: ypos = getPaddingTop() + topMargin; break; case Gravity.BOTTOM: ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight() - bottomMargin; break; } final int customWidth = customView.getMeasuredWidth(); customView.layout(xpos, ypos, xpos + customWidth, ypos + customView.getMeasuredHeight()); x += customWidth; } if (mProgressView != null) { mProgressView.bringToFront(); final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2; mProgressView.layout( mProgressBarPadding, -halfProgressHeight, mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight); } }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int childCount = getChildCount(); if (mIsCollapsable) { int visibleChildren = 0; for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE && !(child == mMenuView && mMenuView.getChildCount() == 0)) { visibleChildren++; } } if (visibleChildren == 0) { // No size for an empty action bar when collapsable. setMeasuredDimension(0, 0); mIsCollapsed = true; return; } } mIsCollapsed = false; int widthMode = MeasureSpec.getMode(widthMeasureSpec); if (widthMode != MeasureSpec.EXACTLY) { throw new IllegalStateException( getClass().getSimpleName() + " can only be used " + "with android:layout_width=\"match_parent\" (or fill_parent)"); } int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (heightMode != MeasureSpec.AT_MOST) { throw new IllegalStateException( getClass().getSimpleName() + " can only be used " + "with android:layout_height=\"wrap_content\""); } int contentWidth = MeasureSpec.getSize(widthMeasureSpec); int maxHeight = mContentHeight > 0 ? mContentHeight : MeasureSpec.getSize(heightMeasureSpec); final int verticalPadding = getPaddingTop() + getPaddingBottom(); final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int height = maxHeight - verticalPadding; final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); int availableWidth = contentWidth - paddingLeft - paddingRight; int leftOfCenter = availableWidth / 2; int rightOfCenter = leftOfCenter; HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; if (homeLayout.getVisibility() != GONE) { final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams(); int homeWidthSpec; if (lp.width < 0) { homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST); } else { homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); } homeLayout.measure(homeWidthSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getLeftOffset(); availableWidth = Math.max(0, availableWidth - homeWidth); leftOfCenter = Math.max(0, availableWidth - homeWidth); } if (mMenuView != null && mMenuView.getParent() == this) { availableWidth = measureChildView(mMenuView, availableWidth, childSpecHeight, 0); rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth()); } if (mIndeterminateProgressView != null && mIndeterminateProgressView.getVisibility() != GONE) { availableWidth = measureChildView(mIndeterminateProgressView, availableWidth, childSpecHeight, 0); rightOfCenter = Math.max(0, rightOfCenter - mIndeterminateProgressView.getMeasuredWidth()); } final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; if (mExpandedActionView == null) { switch (mNavigationMode) { case ActionBar.NAVIGATION_MODE_LIST: if (mListNavLayout != null) { final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; availableWidth = Math.max(0, availableWidth - itemPaddingSize); leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); mListNavLayout.measure( MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); final int listNavWidth = mListNavLayout.getMeasuredWidth(); availableWidth = Math.max(0, availableWidth - listNavWidth); leftOfCenter = Math.max(0, leftOfCenter - listNavWidth); } break; case ActionBar.NAVIGATION_MODE_TABS: if (mTabScrollView != null) { final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; availableWidth = Math.max(0, availableWidth - itemPaddingSize); leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); mTabScrollView.measure( MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); final int tabWidth = mTabScrollView.getMeasuredWidth(); availableWidth = Math.max(0, availableWidth - tabWidth); leftOfCenter = Math.max(0, leftOfCenter - tabWidth); } break; } } View customView = null; if (mExpandedActionView != null) { customView = mExpandedActionView; } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { customView = mCustomNavView; } if (customView != null) { final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams()); final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? (ActionBar.LayoutParams) lp : null; int horizontalMargin = 0; int verticalMargin = 0; if (ablp != null) { horizontalMargin = ablp.leftMargin + ablp.rightMargin; verticalMargin = ablp.topMargin + ablp.bottomMargin; } // If the action bar is wrapping to its content height, don't allow a custom // view to MATCH_PARENT. int customNavHeightMode; if (mContentHeight <= 0) { customNavHeightMode = MeasureSpec.AT_MOST; } else { customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; } final int customNavHeight = Math.max(0, (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin); final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; int customNavWidth = Math.max( 0, (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth) - horizontalMargin); final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) & Gravity.HORIZONTAL_GRAVITY_MASK; // Centering a custom view is treated specially; we try to center within the whole // action bar rather than in the available space. if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) { customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2; } customView.measure( MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode), MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode)); availableWidth -= horizontalMargin + customView.getMeasuredWidth(); } if (mExpandedActionView == null && showTitle) { availableWidth = measureChildView( mTitleLayout, availableWidth, MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0); leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth()); } if (mContentHeight <= 0) { int measuredHeight = 0; for (int i = 0; i < childCount; i++) { View v = getChildAt(i); int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; if (paddedViewHeight > measuredHeight) { measuredHeight = paddedViewHeight; } } setMeasuredDimension(contentWidth, measuredHeight); } else { setMeasuredDimension(contentWidth, maxHeight); } if (mContextView != null) { mContextView.setContentHeight(getMeasuredHeight()); } if (mProgressView != null && mProgressView.getVisibility() != GONE) { mProgressView.measure( MeasureSpec.makeMeasureSpec(contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST)); } }