FileDocCategorySizeDatePackage
Toolbar.javaAPI DocAndroid 5.1 API79179Thu Mar 12 22:22:56 GMT 2015android.support.v7.widget

Toolbar

public class Toolbar extends android.view.ViewGroup
A standard toolbar for use within application content.

A Toolbar is a generalization of {@link ActionBar action bars} for use within application layouts. While an action bar is traditionally part of an {@link android.app.Activity Activity's} opaque window decor controlled by the framework, a Toolbar may be placed at any arbitrary level of nesting within a view hierarchy. An application may choose to designate a Toolbar as the action bar for an Activity using the {@link android.support.v7.app.ActionBarActivity#setSupportActionBar(Toolbar) setSupportActionBar()} method.

Toolbar supports a more focused feature set than ActionBar. From start to end, a toolbar may contain a combination of the following optional elements:

  • A navigation button. This may be an Up arrow, navigation menu toggle, close, collapse, done or another glyph of the app's choosing. This button should always be used to access other navigational destinations within the container of the Toolbar and its signified content or otherwise leave the current context signified by the Toolbar.
  • A branded logo image. This may extend to the height of the bar and can be arbitrarily wide.
  • A title and subtitle. The title should be a signpost for the Toolbar's current position in the navigation hierarchy and the content contained there. The subtitle, if present should indicate any extended information about the current content. If an app uses a logo image it should strongly consider omitting a title and subtitle.
  • One or more custom views. The application may add arbitrary child views to the Toolbar. They will appear at this position within the layout. If a child view's {@link LayoutParams} indicates a {@link Gravity} value of {@link Gravity#CENTER_HORIZONTAL CENTER_HORIZONTAL} the view will attempt to center within the available space remaining in the Toolbar after all other elements have been measured.
  • An {@link ActionMenuView action menu}. The menu of actions will pin to the end of the Toolbar offering a few frequent, important or typical actions along with an optional overflow menu for additional actions.

In modern Android UIs developers should lean more on a visually distinct color scheme for toolbars than on their application icon. The use of application icon plus title as a standard layout is discouraged on API 21 devices and newer.

Fields Summary
private static final String
TAG
private ActionMenuView
mMenuView
private android.widget.TextView
mTitleTextView
private android.widget.TextView
mSubtitleTextView
private android.widget.ImageButton
mNavButtonView
private android.widget.ImageView
mLogoView
private android.graphics.drawable.Drawable
mCollapseIcon
private CharSequence
mCollapseDescription
private android.widget.ImageButton
mCollapseButtonView
android.view.View
mExpandedActionView
private android.content.Context
mPopupContext
Context against which to inflate popup menus.
private int
mPopupTheme
Theme resource against which to inflate popup menus.
private int
mTitleTextAppearance
private int
mSubtitleTextAppearance
private int
mButtonGravity
private int
mMaxButtonHeight
private int
mTitleMarginStart
private int
mTitleMarginEnd
private int
mTitleMarginTop
private int
mTitleMarginBottom
private final android.support.v7.internal.widget.RtlSpacingHelper
mContentInsets
private int
mGravity
private CharSequence
mTitleText
private CharSequence
mSubtitleText
private int
mTitleTextColor
private int
mSubtitleTextColor
private boolean
mEatingTouch
private boolean
mEatingHover
private final ArrayList
mTempViews
private final int[]
mTempMargins
private OnMenuItemClickListener
mOnMenuItemClickListener
private final ActionMenuView.OnMenuItemClickListener
mMenuViewItemClickListener
private android.support.v7.internal.widget.ToolbarWidgetWrapper
mWrapper
private ActionMenuPresenter
mOuterActionMenuPresenter
private ExpandedActionViewMenuPresenter
mExpandedMenuPresenter
private MenuPresenter.Callback
mActionMenuPresenterCallback
private MenuBuilder.Callback
mMenuBuilderCallback
private boolean
mCollapsible
private int
mMinHeight
private final Runnable
mShowOverflowMenuRunnable
private final android.support.v7.internal.widget.TintManager
mTintManager
Constructors Summary
public Toolbar(android.content.Context context)


       
        this(context, null);
    
public Toolbar(android.content.Context context, android.util.AttributeSet attrs)

        this(context, attrs, R.attr.toolbarStyle);
    
public Toolbar(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr)

        super(themifyContext(context, attrs, defStyleAttr), attrs, defStyleAttr);

        // Need to use getContext() here so that we use the themed context
        final TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,
                R.styleable.Toolbar, defStyleAttr, 0);

        mTitleTextAppearance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance, 0);
        mSubtitleTextAppearance = a.getResourceId(R.styleable.Toolbar_subtitleTextAppearance, 0);
        mGravity = a.getInteger(R.styleable.Toolbar_android_gravity, mGravity);
        mButtonGravity = Gravity.TOP;
        mTitleMarginStart = mTitleMarginEnd = mTitleMarginTop = mTitleMarginBottom =
                a.getDimensionPixelOffset(R.styleable.Toolbar_titleMargins, 0);

        final int marginStart = a.getDimensionPixelOffset(R.styleable.Toolbar_titleMarginStart, -1);
        if (marginStart >= 0) {
            mTitleMarginStart = marginStart;
        }

        final int marginEnd = a.getDimensionPixelOffset(R.styleable.Toolbar_titleMarginEnd, -1);
        if (marginEnd >= 0) {
            mTitleMarginEnd = marginEnd;
        }

        final int marginTop = a.getDimensionPixelOffset(R.styleable.Toolbar_titleMarginTop, -1);
        if (marginTop >= 0) {
            mTitleMarginTop = marginTop;
        }

        final int marginBottom = a.getDimensionPixelOffset(R.styleable.Toolbar_titleMarginBottom,
                -1);
        if (marginBottom >= 0) {
            mTitleMarginBottom = marginBottom;
        }

        mMaxButtonHeight = a.getDimensionPixelSize(R.styleable.Toolbar_maxButtonHeight, -1);

        final int contentInsetStart =
                a.getDimensionPixelOffset(R.styleable.Toolbar_contentInsetStart,
                        RtlSpacingHelper.UNDEFINED);
        final int contentInsetEnd =
                a.getDimensionPixelOffset(R.styleable.Toolbar_contentInsetEnd,
                        RtlSpacingHelper.UNDEFINED);
        final int contentInsetLeft =
                a.getDimensionPixelSize(R.styleable.Toolbar_contentInsetLeft, 0);
        final int contentInsetRight =
                a.getDimensionPixelSize(R.styleable.Toolbar_contentInsetRight, 0);

        mContentInsets.setAbsolute(contentInsetLeft, contentInsetRight);

        if (contentInsetStart != RtlSpacingHelper.UNDEFINED ||
                contentInsetEnd != RtlSpacingHelper.UNDEFINED) {
            mContentInsets.setRelative(contentInsetStart, contentInsetEnd);
        }

        mCollapseIcon = a.getDrawable(R.styleable.Toolbar_collapseIcon);
        mCollapseDescription = a.getText(R.styleable.Toolbar_collapseContentDescription);

        final CharSequence title = a.getText(R.styleable.Toolbar_title);
        if (!TextUtils.isEmpty(title)) {
            setTitle(title);
        }

        final CharSequence subtitle = a.getText(R.styleable.Toolbar_subtitle);
        if (!TextUtils.isEmpty(subtitle)) {
            setSubtitle(subtitle);
        }
        // Set the default context, since setPopupTheme() may be a no-op.
        mPopupContext = getContext();
        setPopupTheme(a.getResourceId(R.styleable.Toolbar_popupTheme, 0));

        final Drawable navIcon = a.getDrawable(R.styleable.Toolbar_navigationIcon);
        if (navIcon != null) {
            setNavigationIcon(navIcon);
        }
        final CharSequence navDesc = a.getText(R.styleable.Toolbar_navigationContentDescription);
        if (!TextUtils.isEmpty(navDesc)) {
            setNavigationContentDescription(navDesc);
        }

        // This is read for devices running pre-v16
        mMinHeight = a.getDimensionPixelSize(R.styleable.Toolbar_android_minHeight, 0);

        a.recycle();

        // Keep the TintManager in case we need it later
        mTintManager = a.getTintManager();
    
Methods Summary
private voidaddCustomViewsWithGravity(java.util.List views, int gravity)
Prepare a list of non-SYSTEM child views. If the layout direction is RTL this will be in reverse child order.

param
views List to populate. It will be cleared before use.
param
gravity Horizontal gravity to match against

        final boolean isRtl =  ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
        final int childCount = getChildCount();
        final int absGrav = GravityCompat.getAbsoluteGravity(gravity,
                ViewCompat.getLayoutDirection(this));

        views.clear();

        if (isRtl) {
            for (int i = childCount - 1; i >= 0; i--) {
                final View child = getChildAt(i);
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
                        getChildHorizontalGravity(lp.gravity) == absGrav) {
                    views.add(child);
                }
            }
        } else {
            for (int i = 0; i < childCount; i++) {
                final View child = getChildAt(i);
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
                        getChildHorizontalGravity(lp.gravity) == absGrav) {
                    views.add(child);
                }
            }
        }
    
private voidaddSystemView(android.view.View v)

        final ViewGroup.LayoutParams vlp = v.getLayoutParams();
        final LayoutParams lp;
        if (vlp == null) {
            lp = generateDefaultLayoutParams();
        } else if (!checkLayoutParams(vlp)) {
            lp = generateLayoutParams(vlp);
        } else {
            lp = (LayoutParams) vlp;
        }
        lp.mViewType = LayoutParams.SYSTEM;
        addView(v, lp);
    
public booleancanShowOverflowMenu()

hide

        return getVisibility() == VISIBLE && mMenuView != null && mMenuView.isOverflowReserved();
    
protected booleancheckLayoutParams(ViewGroup.LayoutParams p)

        return super.checkLayoutParams(p) && p instanceof LayoutParams;
    
public voidcollapseActionView()
Collapse a currently expanded action view. If this Toolbar does not have an expanded action view this method has no effect.

An action view may be expanded either directly from the {@link android.view.MenuItem MenuItem} it belongs to or by user action.

see
#hasExpandedActionView()

        final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
                mExpandedMenuPresenter.mCurrentExpandedItem;
        if (item != null) {
            item.collapseActionView();
        }
    
public voiddismissPopupMenus()
Dismiss all currently showing popup menus, including overflow or submenus.

        if (mMenuView != null) {
            mMenuView.dismissPopupMenus();
        }
    
private voidensureCollapseButtonView()

        if (mCollapseButtonView == null) {
            mCollapseButtonView = new ImageButton(getContext(), null,
                    R.attr.toolbarNavigationButtonStyle);
            mCollapseButtonView.setImageDrawable(mCollapseIcon);
            mCollapseButtonView.setContentDescription(mCollapseDescription);
            final LayoutParams lp = generateDefaultLayoutParams();
            lp.gravity = GravityCompat.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
            lp.mViewType = LayoutParams.EXPANDED;
            mCollapseButtonView.setLayoutParams(lp);
            mCollapseButtonView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    collapseActionView();
                }
            });
        }
    
private voidensureLogoView()

        if (mLogoView == null) {
            mLogoView = new ImageView(getContext());
        }
    
private voidensureMenu()

        ensureMenuView();
        if (mMenuView.peekMenu() == null) {
            // Initialize a new menu for the first time.
            final MenuBuilder menu = (MenuBuilder) mMenuView.getMenu();
            if (mExpandedMenuPresenter == null) {
                mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
            }
            mMenuView.setExpandedActionViewsExclusive(true);
            menu.addMenuPresenter(mExpandedMenuPresenter, mPopupContext);
        }
    
private voidensureMenuView()

        if (mMenuView == null) {
            mMenuView = new ActionMenuView(getContext());
            mMenuView.setPopupTheme(mPopupTheme);
            mMenuView.setOnMenuItemClickListener(mMenuViewItemClickListener);
            mMenuView.setMenuCallbacks(mActionMenuPresenterCallback, mMenuBuilderCallback);
            final LayoutParams lp = generateDefaultLayoutParams();
            lp.gravity = GravityCompat.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
            mMenuView.setLayoutParams(lp);
            addSystemView(mMenuView);
        }
    
private voidensureNavButtonView()

        if (mNavButtonView == null) {
            mNavButtonView = new ImageButton(getContext(), null,
                    R.attr.toolbarNavigationButtonStyle);
            final LayoutParams lp = generateDefaultLayoutParams();
            lp.gravity = GravityCompat.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
            mNavButtonView.setLayoutParams(lp);
        }
    
protected android.support.v7.widget.Toolbar$LayoutParamsgenerateDefaultLayoutParams()

        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    
public android.support.v7.widget.Toolbar$LayoutParamsgenerateLayoutParams(android.util.AttributeSet attrs)

        return new LayoutParams(getContext(), attrs);
    
protected android.support.v7.widget.Toolbar$LayoutParamsgenerateLayoutParams(ViewGroup.LayoutParams p)

        if (p instanceof LayoutParams) {
            return new LayoutParams((LayoutParams) p);
        } else if (p instanceof ActionBar.LayoutParams) {
            return new LayoutParams((ActionBar.LayoutParams) p);
        } else if (p instanceof MarginLayoutParams) {
            return new LayoutParams((MarginLayoutParams) p);
        } else {
            return new LayoutParams(p);
        }
    
private intgetChildHorizontalGravity(int gravity)

        final int ld =  ViewCompat.getLayoutDirection(this);
        final int absGrav = GravityCompat.getAbsoluteGravity(gravity, ld);
        final int hGrav = absGrav & Gravity.HORIZONTAL_GRAVITY_MASK;
        switch (hGrav) {
            case Gravity.LEFT:
            case Gravity.RIGHT:
            case Gravity.CENTER_HORIZONTAL:
                return hGrav;
            default:
                return ld == ViewCompat.LAYOUT_DIRECTION_RTL ? Gravity.RIGHT : Gravity.LEFT;
        }
    
private intgetChildTop(android.view.View child, int alignmentHeight)

        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
        final int childHeight = child.getMeasuredHeight();
        final int alignmentOffset = alignmentHeight > 0 ? (childHeight - alignmentHeight) / 2 : 0;
        switch (getChildVerticalGravity(lp.gravity)) {
            case Gravity.TOP:
                return getPaddingTop() - alignmentOffset;

            case Gravity.BOTTOM:
                return getHeight() - getPaddingBottom() - childHeight
                        - lp.bottomMargin - alignmentOffset;

            default:
            case Gravity.CENTER_VERTICAL:
                final int paddingTop = getPaddingTop();
                final int paddingBottom = getPaddingBottom();
                final int height = getHeight();
                final int space = height - paddingTop - paddingBottom;
                int spaceAbove = (space - childHeight) / 2;
                if (spaceAbove < lp.topMargin) {
                    spaceAbove = lp.topMargin;
                } else {
                    final int spaceBelow = height - paddingBottom - childHeight -
                            spaceAbove - paddingTop;
                    if (spaceBelow < lp.bottomMargin) {
                        spaceAbove = Math.max(0, spaceAbove - (lp.bottomMargin - spaceBelow));
                    }
                }
                return paddingTop + spaceAbove;
        }
    
private intgetChildVerticalGravity(int gravity)

        final int vgrav = gravity & Gravity.VERTICAL_GRAVITY_MASK;
        switch (vgrav) {
            case Gravity.TOP:
            case Gravity.BOTTOM:
            case Gravity.CENTER_VERTICAL:
                return vgrav;
            default:
                return mGravity & Gravity.VERTICAL_GRAVITY_MASK;
        }
    
public intgetContentInsetEnd()
Get the ending content inset for this toolbar.

The content inset affects the valid area for Toolbar content other than the navigation button and menu. Insets define the minimum margin for these components and can be used to effectively align Toolbar content along well-known gridlines.

return
The ending content inset for this toolbar
see
#setContentInsetsRelative(int, int)
see
#setContentInsetsAbsolute(int, int)
see
#getContentInsetStart()
see
#getContentInsetLeft()
see
#getContentInsetRight()

        return mContentInsets.getEnd();
    
public intgetContentInsetLeft()
Get the left content inset for this toolbar.

The content inset affects the valid area for Toolbar content other than the navigation button and menu. Insets define the minimum margin for these components and can be used to effectively align Toolbar content along well-known gridlines.

return
The left content inset for this toolbar
see
#setContentInsetsRelative(int, int)
see
#setContentInsetsAbsolute(int, int)
see
#getContentInsetStart()
see
#getContentInsetEnd()
see
#getContentInsetRight()

        return mContentInsets.getLeft();
    
public intgetContentInsetRight()
Get the right content inset for this toolbar.

The content inset affects the valid area for Toolbar content other than the navigation button and menu. Insets define the minimum margin for these components and can be used to effectively align Toolbar content along well-known gridlines.

return
The right content inset for this toolbar
see
#setContentInsetsRelative(int, int)
see
#setContentInsetsAbsolute(int, int)
see
#getContentInsetStart()
see
#getContentInsetEnd()
see
#getContentInsetLeft()

        return mContentInsets.getRight();
    
public intgetContentInsetStart()
Get the starting content inset for this toolbar.

The content inset affects the valid area for Toolbar content other than the navigation button and menu. Insets define the minimum margin for these components and can be used to effectively align Toolbar content along well-known gridlines.

return
The starting content inset for this toolbar
see
#setContentInsetsRelative(int, int)
see
#setContentInsetsAbsolute(int, int)
see
#getContentInsetEnd()
see
#getContentInsetLeft()
see
#getContentInsetRight()

        return mContentInsets.getStart();
    
private intgetHorizontalMargins(android.view.View v)

        final MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
        return MarginLayoutParamsCompat.getMarginStart(mlp) +
                MarginLayoutParamsCompat.getMarginEnd(mlp);
    
public android.graphics.drawable.DrawablegetLogo()
Return the current logo drawable.

return
The current logo drawable
see
#setLogo(int)
see
#setLogo(android.graphics.drawable.Drawable)

        return mLogoView != null ? mLogoView.getDrawable() : null;
    
public java.lang.CharSequencegetLogoDescription()
Return the description of the toolbar's logo.

return
A description of the logo

        return mLogoView != null ? mLogoView.getContentDescription() : null;
    
public android.view.MenugetMenu()
Return the Menu shown in the toolbar.

Applications that wish to populate the toolbar's menu can do so from here. To use an XML menu resource, use {@link #inflateMenu(int)}.

return
The toolbar's Menu

        ensureMenu();
        return mMenuView.getMenu();
    
private android.view.MenuInflatergetMenuInflater()

        return new SupportMenuInflater(getContext());
    
private intgetMinimumHeightCompat()

        if (Build.VERSION.SDK_INT >= 16) {
            // If we're running on API 16 or newer, use the platform method
            return ViewCompat.getMinimumHeight(this);
        } else {
            // Else we'll use our locally kept value
            return mMinHeight;
        }
    
public java.lang.CharSequencegetNavigationContentDescription()
Retrieve the currently configured content description for the navigation button view. This will be used to describe the navigation action to users through mechanisms such as screen readers or tooltips.

return
The navigation button's content description

        return mNavButtonView != null ? mNavButtonView.getContentDescription() : null;
    
public android.graphics.drawable.DrawablegetNavigationIcon()
Return the current drawable used as the navigation icon.

return
The navigation icon drawable

        return mNavButtonView != null ? mNavButtonView.getDrawable() : null;
    
public intgetPopupTheme()

return
resource identifier of the theme used to inflate popup menus, or 0 if menus are inflated against the toolbar theme
see
#setPopupTheme(int)

        return mPopupTheme;
    
public java.lang.CharSequencegetSubtitle()
Return the subtitle of this toolbar.

return
The current subtitle

        return mSubtitleText;
    
public java.lang.CharSequencegetTitle()
Returns the title of this toolbar.

return
The current title.

        return mTitleText;
    
private intgetVerticalMargins(android.view.View v)

        final MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
        return mlp.topMargin + mlp.bottomMargin;
    
private intgetViewListMeasuredWidth(java.util.List views, int[] collapsingMargins)

        int collapseLeft = collapsingMargins[0];
        int collapseRight = collapsingMargins[1];
        int width = 0;
        final int count = views.size();
        for (int i = 0; i < count; i++) {
            final View v = views.get(i);
            final LayoutParams lp = (LayoutParams) v.getLayoutParams();
            final int l = lp.leftMargin - collapseLeft;
            final int r = lp.rightMargin - collapseRight;
            final int leftMargin = Math.max(0, l);
            final int rightMargin = Math.max(0, r);
            collapseLeft = Math.max(0, -l);
            collapseRight = Math.max(0, -r);
            width += leftMargin + v.getMeasuredWidth() + rightMargin;
        }
        return width;
    
public android.support.v7.internal.widget.DecorToolbargetWrapper()

hide

        if (mWrapper == null) {
            mWrapper = new ToolbarWidgetWrapper(this, true);
        }
        return mWrapper;
    
public booleanhasExpandedActionView()
Check whether this Toolbar is currently hosting an expanded action view.

An action view may be expanded either directly from the {@link android.view.MenuItem MenuItem} it belongs to or by user action. If the Toolbar has an expanded action view it can be collapsed using the {@link #collapseActionView()} method.

return
true if the Toolbar has an expanded action view

        return mExpandedMenuPresenter != null &&
                mExpandedMenuPresenter.mCurrentExpandedItem != null;
    
public booleanhideOverflowMenu()
Hide the overflow items from the associated menu.

return
true if the menu was able to be hidden, false otherwise

        return mMenuView != null && mMenuView.hideOverflowMenu();
    
public voidinflateMenu(int resId)
Inflate a menu resource into this toolbar.

Inflate an XML menu resource into this toolbar. Existing items in the menu will not be modified or removed.

param
resId ID of a menu resource to inflate

        getMenuInflater().inflate(resId, getMenu());
    
private static booleanisCustomView(android.view.View child)

        return ((LayoutParams) child.getLayoutParams()).mViewType == LayoutParams.CUSTOM;
    
public booleanisOverflowMenuShowPending()

hide

        return mMenuView != null && mMenuView.isOverflowMenuShowPending();
    
public booleanisOverflowMenuShowing()
Check whether the overflow menu is currently showing. This may not reflect a pending show operation in progress.

return
true if the overflow menu is currently showing

        return mMenuView != null && mMenuView.isOverflowMenuShowing();
    
public booleanisTitleTruncated()

hide

        if (mTitleTextView == null) {
            return false;
        }

        final Layout titleLayout = mTitleTextView.getLayout();
        if (titleLayout == null) {
            return false;
        }

        final int lineCount = titleLayout.getLineCount();
        for (int i = 0; i < lineCount; i++) {
            if (titleLayout.getEllipsisCount(i) > 0) {
                return true;
            }
        }
        return false;
    
private intlayoutChildLeft(android.view.View child, int left, int[] collapsingMargins, int alignmentHeight)

        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
        final int l = lp.leftMargin - collapsingMargins[0];
        left += Math.max(0, l);
        collapsingMargins[0] = Math.max(0, -l);
        final int top = getChildTop(child, alignmentHeight);
        final int childWidth = child.getMeasuredWidth();
        child.layout(left, top, left + childWidth, top + child.getMeasuredHeight());
        left += childWidth + lp.rightMargin;
        return left;
    
private intlayoutChildRight(android.view.View child, int right, int[] collapsingMargins, int alignmentHeight)

        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
        final int r = lp.rightMargin - collapsingMargins[1];
        right -= Math.max(0, r);
        collapsingMargins[1] = Math.max(0, -r);
        final int top = getChildTop(child, alignmentHeight);
        final int childWidth = child.getMeasuredWidth();
        child.layout(right - childWidth, top, right, top + child.getMeasuredHeight());
        right -= childWidth + lp.leftMargin;
        return right;
    
private intmeasureChildCollapseMargins(android.view.View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed, int[] collapsingMargins)
Returns the width + uncollapsed margins

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

        final int leftDiff = lp.leftMargin - collapsingMargins[0];
        final int rightDiff = lp.rightMargin - collapsingMargins[1];
        final int leftMargin = Math.max(0, leftDiff);
        final int rightMargin = Math.max(0, rightDiff);
        final int hMargins = leftMargin + rightMargin;
        collapsingMargins[0] = Math.max(0, -leftDiff);
        collapsingMargins[1] = Math.max(0, -rightDiff);

        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
                getPaddingLeft() + getPaddingRight() + hMargins + widthUsed, lp.width);
        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
                getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin
                        + heightUsed, lp.height);

        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
        return child.getMeasuredWidth() + hMargins;
    
private voidmeasureChildConstrained(android.view.View child, int parentWidthSpec, int widthUsed, int parentHeightSpec, int heightUsed, int heightConstraint)

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

        int childWidthSpec = getChildMeasureSpec(parentWidthSpec,
                getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin
                        + widthUsed, lp.width);
        int childHeightSpec = getChildMeasureSpec(parentHeightSpec,
                getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin
                        + heightUsed, lp.height);

        final int childHeightMode = MeasureSpec.getMode(childHeightSpec);
        if (childHeightMode != MeasureSpec.EXACTLY && heightConstraint >= 0) {
            final int size = childHeightMode != MeasureSpec.UNSPECIFIED ?
                    Math.min(MeasureSpec.getSize(childHeightSpec), heightConstraint) :
                    heightConstraint;
            childHeightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
        }
        child.measure(childWidthSpec, childHeightSpec);
    
protected voidonDetachedFromWindow()

        super.onDetachedFromWindow();
        removeCallbacks(mShowOverflowMenuRunnable);
    
public booleanonHoverEvent(android.view.MotionEvent ev)

        // Same deal as onTouchEvent() above. Eat all hover events, but still
        // respect the touch event dispatch contract.

        final int action = MotionEventCompat.getActionMasked(ev);
        if (action == MotionEvent.ACTION_HOVER_ENTER) {
            mEatingHover = false;
        }

        if (!mEatingHover) {
            final boolean handled = super.onHoverEvent(ev);
            if (action == MotionEvent.ACTION_HOVER_ENTER && !handled) {
                mEatingHover = true;
            }
        }

        if (action == MotionEvent.ACTION_HOVER_EXIT || action == MotionEvent.ACTION_CANCEL) {
            mEatingHover = false;
        }

        return true;
    
protected voidonLayout(boolean changed, int l, int t, int r, int b)

        final boolean isRtl =  ViewCompat.getLayoutDirection(this) ==  ViewCompat.LAYOUT_DIRECTION_RTL;
        final int width = getWidth();
        final int height = getHeight();
        final int paddingLeft = getPaddingLeft();
        final int paddingRight = getPaddingRight();
        final int paddingTop = getPaddingTop();
        final int paddingBottom = getPaddingBottom();
        int left = paddingLeft;
        int right = width - paddingRight;

        final int[] collapsingMargins = mTempMargins;
        collapsingMargins[0] = collapsingMargins[1] = 0;

        // Align views within the minimum toolbar height, if set.
        final int alignmentHeight = getMinimumHeightCompat();

        if (shouldLayout(mNavButtonView)) {
            if (isRtl) {
                right = layoutChildRight(mNavButtonView, right, collapsingMargins,
                        alignmentHeight);
            } else {
                left = layoutChildLeft(mNavButtonView, left, collapsingMargins,
                        alignmentHeight);
            }
        }

        if (shouldLayout(mCollapseButtonView)) {
            if (isRtl) {
                right = layoutChildRight(mCollapseButtonView, right, collapsingMargins,
                        alignmentHeight);
            } else {
                left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins,
                        alignmentHeight);
            }
        }

        if (shouldLayout(mMenuView)) {
            if (isRtl) {
                left = layoutChildLeft(mMenuView, left, collapsingMargins,
                        alignmentHeight);
            } else {
                right = layoutChildRight(mMenuView, right, collapsingMargins,
                        alignmentHeight);
            }
        }

        collapsingMargins[0] = Math.max(0, getContentInsetLeft() - left);
        collapsingMargins[1] = Math.max(0, getContentInsetRight() - (width - paddingRight - right));
        left = Math.max(left, getContentInsetLeft());
        right = Math.min(right, width - paddingRight - getContentInsetRight());

        if (shouldLayout(mExpandedActionView)) {
            if (isRtl) {
                right = layoutChildRight(mExpandedActionView, right, collapsingMargins,
                        alignmentHeight);
            } else {
                left = layoutChildLeft(mExpandedActionView, left, collapsingMargins,
                        alignmentHeight);
            }
        }

        if (shouldLayout(mLogoView)) {
            if (isRtl) {
                right = layoutChildRight(mLogoView, right, collapsingMargins,
                        alignmentHeight);
            } else {
                left = layoutChildLeft(mLogoView, left, collapsingMargins,
                        alignmentHeight);
            }
        }

        final boolean layoutTitle = shouldLayout(mTitleTextView);
        final boolean layoutSubtitle = shouldLayout(mSubtitleTextView);
        int titleHeight = 0;
        if (layoutTitle) {
            final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
            titleHeight += lp.topMargin + mTitleTextView.getMeasuredHeight() + lp.bottomMargin;
        }
        if (layoutSubtitle) {
            final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams();
            titleHeight += lp.topMargin + mSubtitleTextView.getMeasuredHeight() + lp.bottomMargin;
        }

        if (layoutTitle || layoutSubtitle) {
            int titleTop;
            final View topChild = layoutTitle ? mTitleTextView : mSubtitleTextView;
            final View bottomChild = layoutSubtitle ? mSubtitleTextView : mTitleTextView;
            final LayoutParams toplp = (LayoutParams) topChild.getLayoutParams();
            final LayoutParams bottomlp = (LayoutParams) bottomChild.getLayoutParams();
            final boolean titleHasWidth = layoutTitle && mTitleTextView.getMeasuredWidth() > 0
                    || layoutSubtitle && mSubtitleTextView.getMeasuredWidth() > 0;

            switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) {
                case Gravity.TOP:
                    titleTop = getPaddingTop() + toplp.topMargin + mTitleMarginTop;
                    break;
                default:
                case Gravity.CENTER_VERTICAL:
                    final int space = height - paddingTop - paddingBottom;
                    int spaceAbove = (space - titleHeight) / 2;
                    if (spaceAbove < toplp.topMargin + mTitleMarginTop) {
                        spaceAbove = toplp.topMargin + mTitleMarginTop;
                    } else {
                        final int spaceBelow = height - paddingBottom - titleHeight -
                                spaceAbove - paddingTop;
                        if (spaceBelow < toplp.bottomMargin + mTitleMarginBottom) {
                            spaceAbove = Math.max(0, spaceAbove -
                                    (bottomlp.bottomMargin + mTitleMarginBottom - spaceBelow));
                        }
                    }
                    titleTop = paddingTop + spaceAbove;
                    break;
                case Gravity.BOTTOM:
                    titleTop = height - paddingBottom - bottomlp.bottomMargin - mTitleMarginBottom -
                            titleHeight;
                    break;
            }
            if (isRtl) {
                final int rd = (titleHasWidth ? mTitleMarginStart : 0) - collapsingMargins[1];
                right -= Math.max(0, rd);
                collapsingMargins[1] = Math.max(0, -rd);
                int titleRight = right;
                int subtitleRight = right;

                if (layoutTitle) {
                    final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
                    final int titleLeft = titleRight - mTitleTextView.getMeasuredWidth();
                    final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
                    mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
                    titleRight = titleLeft - mTitleMarginEnd;
                    titleTop = titleBottom + lp.bottomMargin;
                }
                if (layoutSubtitle) {
                    final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams();
                    titleTop += lp.topMargin;
                    final int subtitleLeft = subtitleRight - mSubtitleTextView.getMeasuredWidth();
                    final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight();
                    mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom);
                    subtitleRight = subtitleRight - mTitleMarginEnd;
                    titleTop = subtitleBottom + lp.bottomMargin;
                }
                if (titleHasWidth) {
                    right = Math.min(titleRight, subtitleRight);
                }
            } else {
                final int ld = (titleHasWidth ? mTitleMarginStart : 0) - collapsingMargins[0];
                left += Math.max(0, ld);
                collapsingMargins[0] = Math.max(0, -ld);
                int titleLeft = left;
                int subtitleLeft = left;

                if (layoutTitle) {
                    final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
                    final int titleRight = titleLeft + mTitleTextView.getMeasuredWidth();
                    final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
                    mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
                    titleLeft = titleRight + mTitleMarginEnd;
                    titleTop = titleBottom + lp.bottomMargin;
                }
                if (layoutSubtitle) {
                    final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams();
                    titleTop += lp.topMargin;
                    final int subtitleRight = subtitleLeft + mSubtitleTextView.getMeasuredWidth();
                    final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight();
                    mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom);
                    subtitleLeft = subtitleRight + mTitleMarginEnd;
                    titleTop = subtitleBottom + lp.bottomMargin;
                }
                if (titleHasWidth) {
                    left = Math.max(titleLeft, subtitleLeft);
                }
            }
        }

        // Get all remaining children sorted for layout. This is all prepared
        // such that absolute layout direction can be used below.

        addCustomViewsWithGravity(mTempViews, Gravity.LEFT);
        final int leftViewsCount = mTempViews.size();
        for (int i = 0; i < leftViewsCount; i++) {
            left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins,
                    alignmentHeight);
        }

        addCustomViewsWithGravity(mTempViews, Gravity.RIGHT);
        final int rightViewsCount = mTempViews.size();
        for (int i = 0; i < rightViewsCount; i++) {
            right = layoutChildRight(mTempViews.get(i), right, collapsingMargins,
                    alignmentHeight);
        }

        // Centered views try to center with respect to the whole bar, but views pinned
        // to the left or right can push the mass of centered views to one side or the other.
        addCustomViewsWithGravity(mTempViews, Gravity.CENTER_HORIZONTAL);
        final int centerViewsWidth = getViewListMeasuredWidth(mTempViews, collapsingMargins);
        final int parentCenter = paddingLeft + (width - paddingLeft - paddingRight) / 2;
        final int halfCenterViewsWidth = centerViewsWidth / 2;
        int centerLeft = parentCenter - halfCenterViewsWidth;
        final int centerRight = centerLeft + centerViewsWidth;
        if (centerLeft < left) {
            centerLeft = left;
        } else if (centerRight > right) {
            centerLeft -= centerRight - right;
        }

        final int centerViewsCount = mTempViews.size();
        for (int i = 0; i < centerViewsCount; i++) {
            centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins,
                    alignmentHeight);
        }

        mTempViews.clear();
    
protected voidonMeasure(int widthMeasureSpec, int heightMeasureSpec)

        int width = 0;
        int height = 0;
        int childState = 0;

        final int[] collapsingMargins = mTempMargins;
        final int marginStartIndex;
        final int marginEndIndex;
        if (ViewUtils.isLayoutRtl(this)) {
            marginStartIndex = 1;
            marginEndIndex = 0;
        } else {
            marginStartIndex = 0;
            marginEndIndex = 1;
        }

        // System views measure first.

        int navWidth = 0;
        if (shouldLayout(mNavButtonView)) {
            measureChildConstrained(mNavButtonView, widthMeasureSpec, width, heightMeasureSpec, 0,
                    mMaxButtonHeight);
            navWidth = mNavButtonView.getMeasuredWidth() + getHorizontalMargins(mNavButtonView);
            height = Math.max(height, mNavButtonView.getMeasuredHeight() +
                    getVerticalMargins(mNavButtonView));
            childState = ViewUtils.combineMeasuredStates(childState,
                    ViewCompat.getMeasuredState(mNavButtonView));
        }

        if (shouldLayout(mCollapseButtonView)) {
            measureChildConstrained(mCollapseButtonView, widthMeasureSpec, width,
                    heightMeasureSpec, 0, mMaxButtonHeight);
            navWidth = mCollapseButtonView.getMeasuredWidth() +
                    getHorizontalMargins(mCollapseButtonView);
            height = Math.max(height, mCollapseButtonView.getMeasuredHeight() +
                    getVerticalMargins(mCollapseButtonView));
            childState = ViewUtils.combineMeasuredStates(childState,
                    ViewCompat.getMeasuredState(mCollapseButtonView));
        }

        final int contentInsetStart = getContentInsetStart();
        width += Math.max(contentInsetStart, navWidth);
        collapsingMargins[marginStartIndex] = Math.max(0, contentInsetStart - navWidth);

        int menuWidth = 0;
        if (shouldLayout(mMenuView)) {
            measureChildConstrained(mMenuView, widthMeasureSpec, width, heightMeasureSpec, 0,
                    mMaxButtonHeight);
            menuWidth = mMenuView.getMeasuredWidth() + getHorizontalMargins(mMenuView);
            height = Math.max(height, mMenuView.getMeasuredHeight() +
                    getVerticalMargins(mMenuView));
            childState = ViewUtils.combineMeasuredStates(childState,
                    ViewCompat.getMeasuredState(mMenuView));
        }

        final int contentInsetEnd = getContentInsetEnd();
        width += Math.max(contentInsetEnd, menuWidth);
        collapsingMargins[marginEndIndex] = Math.max(0, contentInsetEnd - menuWidth);

        if (shouldLayout(mExpandedActionView)) {
            width += measureChildCollapseMargins(mExpandedActionView, widthMeasureSpec, width,
                    heightMeasureSpec, 0, collapsingMargins);
            height = Math.max(height, mExpandedActionView.getMeasuredHeight() +
                    getVerticalMargins(mExpandedActionView));
            childState = ViewUtils.combineMeasuredStates(childState,
                    ViewCompat.getMeasuredState(mExpandedActionView));
        }

        if (shouldLayout(mLogoView)) {
            width += measureChildCollapseMargins(mLogoView, widthMeasureSpec, width,
                    heightMeasureSpec, 0, collapsingMargins);
            height = Math.max(height, mLogoView.getMeasuredHeight() +
                    getVerticalMargins(mLogoView));
            childState = ViewUtils.combineMeasuredStates(childState,
                    ViewCompat.getMeasuredState(mLogoView));
        }

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (lp.mViewType != LayoutParams.CUSTOM || !shouldLayout(child)) {
                // We already got all system views above. Skip them and GONE views.
                continue;
            }

            width += measureChildCollapseMargins(child, widthMeasureSpec, width,
                    heightMeasureSpec, 0, collapsingMargins);
            height = Math.max(height, child.getMeasuredHeight() + getVerticalMargins(child));
            childState = ViewUtils.combineMeasuredStates(childState,
                    ViewCompat.getMeasuredState(child));
        }

        int titleWidth = 0;
        int titleHeight = 0;
        final int titleVertMargins = mTitleMarginTop + mTitleMarginBottom;
        final int titleHorizMargins = mTitleMarginStart + mTitleMarginEnd;
        if (shouldLayout(mTitleTextView)) {
            titleWidth = measureChildCollapseMargins(mTitleTextView, widthMeasureSpec,
                    width + titleHorizMargins, heightMeasureSpec, titleVertMargins,
                    collapsingMargins);
            titleWidth = mTitleTextView.getMeasuredWidth() + getHorizontalMargins(mTitleTextView);
            titleHeight = mTitleTextView.getMeasuredHeight() + getVerticalMargins(mTitleTextView);
            childState = ViewUtils.combineMeasuredStates(childState,
                    ViewCompat.getMeasuredState(mTitleTextView));
        }
        if (shouldLayout(mSubtitleTextView)) {
            titleWidth = Math.max(titleWidth, measureChildCollapseMargins(mSubtitleTextView,
                    widthMeasureSpec, width + titleHorizMargins,
                    heightMeasureSpec, titleHeight + titleVertMargins,
                    collapsingMargins));
            titleHeight += mSubtitleTextView.getMeasuredHeight() +
                    getVerticalMargins(mSubtitleTextView);
            childState = ViewUtils.combineMeasuredStates(childState,
                    ViewCompat.getMeasuredState(mSubtitleTextView));
        }

        width += titleWidth;
        height = Math.max(height, titleHeight);

        // Measurement already took padding into account for available space for the children,
        // add it in for the final size.
        width += getPaddingLeft() + getPaddingRight();
        height += getPaddingTop() + getPaddingBottom();

        final int measuredWidth = ViewCompat.resolveSizeAndState(
                Math.max(width, getSuggestedMinimumWidth()),
                widthMeasureSpec, childState & ViewCompat.MEASURED_STATE_MASK);
        final int measuredHeight = ViewCompat.resolveSizeAndState(
                Math.max(height, getSuggestedMinimumHeight()),
                heightMeasureSpec, childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);

        setMeasuredDimension(measuredWidth, shouldCollapse() ? 0 : measuredHeight);
    
protected voidonRestoreInstanceState(android.os.Parcelable state)

        final SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());

        final Menu menu = mMenuView != null ? mMenuView.peekMenu() : null;
        if (ss.expandedMenuItemId != 0 && mExpandedMenuPresenter != null && menu != null) {
            final MenuItem item = menu.findItem(ss.expandedMenuItemId);
            if (item != null) {
                MenuItemCompat.expandActionView(item);
            }
        }

        if (ss.isOverflowOpen) {
            postShowOverflowMenu();
        }
    
public voidonRtlPropertiesChanged(int layoutDirection)

        if (Build.VERSION.SDK_INT >= 17) {
            super.onRtlPropertiesChanged(layoutDirection);
        }
        mContentInsets.setDirection(layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL);
    
protected android.os.ParcelableonSaveInstanceState()

        SavedState state = new SavedState(super.onSaveInstanceState());

        if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) {
            state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId();
        }

        state.isOverflowOpen = isOverflowMenuShowing();
        return state;
    
public booleanonTouchEvent(android.view.MotionEvent ev)

        // Toolbars always eat touch events, but should still respect the touch event dispatch
        // contract. If the normal View implementation doesn't want the events, we'll just silently
        // eat the rest of the gesture without reporting the events to the default implementation
        // since that's what it expects.

        final int action = MotionEventCompat.getActionMasked(ev);
        if (action == MotionEvent.ACTION_DOWN) {
            mEatingTouch = false;
        }

        if (!mEatingTouch) {
            final boolean handled = super.onTouchEvent(ev);
            if (action == MotionEvent.ACTION_DOWN && !handled) {
                mEatingTouch = true;
            }
        }

        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            mEatingTouch = false;
        }

        return true;
    
private voidpostShowOverflowMenu()

        removeCallbacks(mShowOverflowMenuRunnable);
        post(mShowOverflowMenuRunnable);
    
private voidsetChildVisibilityForExpandedActionView(boolean expand)

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
                child.setVisibility(expand ? GONE : VISIBLE);
            }
        }
    
public voidsetCollapsible(boolean collapsible)
Force the toolbar to collapse to zero-height during measurement if it could be considered "empty" (no visible elements with nonzero measured size)

hide

        mCollapsible = collapsible;
        requestLayout();
    
public voidsetContentInsetsAbsolute(int contentInsetLeft, int contentInsetRight)
Set the content insets for this toolbar.

The content inset affects the valid area for Toolbar content other than the navigation button and menu. Insets define the minimum margin for these components and can be used to effectively align Toolbar content along well-known gridlines.

param
contentInsetLeft Content inset for the toolbar's left edge
param
contentInsetRight Content inset for the toolbar's right edge
see
#setContentInsetsAbsolute(int, int)
see
#getContentInsetStart()
see
#getContentInsetEnd()
see
#getContentInsetLeft()
see
#getContentInsetRight()

        mContentInsets.setAbsolute(contentInsetLeft, contentInsetRight);
    
public voidsetContentInsetsRelative(int contentInsetStart, int contentInsetEnd)
Set the content insets for this toolbar relative to layout direction.

The content inset affects the valid area for Toolbar content other than the navigation button and menu. Insets define the minimum margin for these components and can be used to effectively align Toolbar content along well-known gridlines.

param
contentInsetStart Content inset for the toolbar starting edge
param
contentInsetEnd Content inset for the toolbar ending edge
see
#setContentInsetsAbsolute(int, int)
see
#getContentInsetStart()
see
#getContentInsetEnd()
see
#getContentInsetLeft()
see
#getContentInsetRight()

        mContentInsets.setRelative(contentInsetStart, contentInsetEnd);
    
public voidsetLogo(android.graphics.drawable.Drawable drawable)
Set a logo drawable.

This drawable should generally take the place of title text. The logo cannot be clicked. Apps using a logo should also supply a description using {@link #setLogoDescription(int)}.

param
drawable Drawable to use as a logo

        if (drawable != null) {
            ensureLogoView();
            if (mLogoView.getParent() == null) {
                addSystemView(mLogoView);
                updateChildVisibilityForExpandedActionView(mLogoView);
            }
        } else if (mLogoView != null && mLogoView.getParent() != null) {
            removeView(mLogoView);
        }
        if (mLogoView != null) {
            mLogoView.setImageDrawable(drawable);
        }
    
public voidsetLogo(int resId)
Set a logo drawable from a resource id.

This drawable should generally take the place of title text. The logo cannot be clicked. Apps using a logo should also supply a description using {@link #setLogoDescription(int)}.

param
resId ID of a drawable resource

        setLogo(mTintManager.getDrawable(resId));
    
public voidsetLogoDescription(int resId)
Set a description of the toolbar's logo.

This description will be used for accessibility or other similar descriptions of the UI.

param
resId String resource id

        setLogoDescription(getContext().getText(resId));
    
public voidsetLogoDescription(java.lang.CharSequence description)
Set a description of the toolbar's logo.

This description will be used for accessibility or other similar descriptions of the UI.

param
description Description to set

        if (!TextUtils.isEmpty(description)) {
            ensureLogoView();
        }
        if (mLogoView != null) {
            mLogoView.setContentDescription(description);
        }
    
public voidsetMenu(android.support.v7.internal.view.menu.MenuBuilder menu, ActionMenuPresenter outerPresenter)

hide

        if (menu == null && mMenuView == null) {
            return;
        }

        ensureMenuView();
        final MenuBuilder oldMenu = mMenuView.peekMenu();
        if (oldMenu == menu) {
            return;
        }

        if (oldMenu != null) {
            oldMenu.removeMenuPresenter(mOuterActionMenuPresenter);
            oldMenu.removeMenuPresenter(mExpandedMenuPresenter);
        }

        if (mExpandedMenuPresenter == null) {
            mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
        }

        outerPresenter.setExpandedActionViewsExclusive(true);
        if (menu != null) {
            menu.addMenuPresenter(outerPresenter, mPopupContext);
            menu.addMenuPresenter(mExpandedMenuPresenter, mPopupContext);
        } else {
            outerPresenter.initForMenu(mPopupContext, null);
            mExpandedMenuPresenter.initForMenu(mPopupContext, null);
            outerPresenter.updateMenuView(true);
            mExpandedMenuPresenter.updateMenuView(true);
        }
        mMenuView.setPopupTheme(mPopupTheme);
        mMenuView.setPresenter(outerPresenter);
        mOuterActionMenuPresenter = outerPresenter;
    
public voidsetMenuCallbacks(MenuPresenter.Callback pcb, MenuBuilder.Callback mcb)
Must be called before the menu is accessed

hide

        mActionMenuPresenterCallback = pcb;
        mMenuBuilderCallback = mcb;
    
public voidsetMinimumHeight(int minHeight)

        // Update our locally kept value
        mMinHeight = minHeight;

        super.setMinimumHeight(minHeight);
    
public voidsetNavigationContentDescription(int resId)
Set a content description for the navigation button if one is present. The content description will be read via screen readers or other accessibility systems to explain the action of the navigation button.

param
resId Resource ID of a content description string to set, or 0 to clear the description

        setNavigationContentDescription(resId != 0 ? getContext().getText(resId) : null);
    
public voidsetNavigationContentDescription(java.lang.CharSequence description)
Set a content description for the navigation button if one is present. The content description will be read via screen readers or other accessibility systems to explain the action of the navigation button.

param
description Content description to set, or null to clear the content description

        if (!TextUtils.isEmpty(description)) {
            ensureNavButtonView();
        }
        if (mNavButtonView != null) {
            mNavButtonView.setContentDescription(description);
        }
    
public voidsetNavigationIcon(int resId)
Set the icon to use for the toolbar's navigation button.

The navigation button appears at the start of the toolbar if present. Setting an icon will make the navigation button visible.

If you use a navigation icon you should also set a description for its action using {@link #setNavigationContentDescription(int)}. This is used for accessibility and tooltips.

param
resId Resource ID of a drawable to set

        setNavigationIcon(mTintManager.getDrawable(resId));
    
public voidsetNavigationIcon(android.graphics.drawable.Drawable icon)
Set the icon to use for the toolbar's navigation button.

The navigation button appears at the start of the toolbar if present. Setting an icon will make the navigation button visible.

If you use a navigation icon you should also set a description for its action using {@link #setNavigationContentDescription(int)}. This is used for accessibility and tooltips.

param
icon Drawable to set, may be null to clear the icon

        if (icon != null) {
            ensureNavButtonView();
            if (mNavButtonView.getParent() == null) {
                addSystemView(mNavButtonView);
                updateChildVisibilityForExpandedActionView(mNavButtonView);
            }
        } else if (mNavButtonView != null && mNavButtonView.getParent() != null) {
            removeView(mNavButtonView);
        }
        if (mNavButtonView != null) {
            mNavButtonView.setImageDrawable(icon);
        }
    
public voidsetNavigationOnClickListener(OnClickListener listener)
Set a listener to respond to navigation events.

This listener will be called whenever the user clicks the navigation button at the start of the toolbar. An icon must be set for the navigation button to appear.

param
listener Listener to set
see
#setNavigationIcon(android.graphics.drawable.Drawable)

        ensureNavButtonView();
        mNavButtonView.setOnClickListener(listener);
    
public voidsetOnMenuItemClickListener(android.support.v7.widget.Toolbar$OnMenuItemClickListener listener)
Set a listener to respond to menu item click events.

This listener will be invoked whenever a user selects a menu item from the action buttons presented at the end of the toolbar or the associated overflow.

param
listener Listener to set

        mOnMenuItemClickListener = listener;
    
public voidsetPopupTheme(int resId)
Specifies the theme to use when inflating popup menus. By default, uses the same theme as the toolbar itself.

param
resId theme used to inflate popup menus
see
#getPopupTheme()

        if (mPopupTheme != resId) {
            mPopupTheme = resId;
            if (resId == 0) {
                mPopupContext = getContext();
            } else {
                mPopupContext = new ContextThemeWrapper(getContext(), resId);
            }
        }
    
public voidsetSubtitle(int resId)
Set the subtitle of this toolbar.

Subtitles should express extended information about the current content.

param
resId String resource ID

        setSubtitle(getContext().getText(resId));
    
public voidsetSubtitle(java.lang.CharSequence subtitle)
Set the subtitle of this toolbar.

Subtitles should express extended information about the current content.

param
subtitle Subtitle to set

        if (!TextUtils.isEmpty(subtitle)) {
            if (mSubtitleTextView == null) {
                final Context context = getContext();
                mSubtitleTextView = new TextView(context);
                mSubtitleTextView.setSingleLine();
                mSubtitleTextView.setEllipsize(TextUtils.TruncateAt.END);
                if (mSubtitleTextAppearance != 0) {
                    mSubtitleTextView.setTextAppearance(context, mSubtitleTextAppearance);
                }
                if (mSubtitleTextColor != 0) {
                    mSubtitleTextView.setTextColor(mSubtitleTextColor);
                }
            }
            if (mSubtitleTextView.getParent() == null) {
                addSystemView(mSubtitleTextView);
                updateChildVisibilityForExpandedActionView(mSubtitleTextView);
            }
        } else if (mSubtitleTextView != null && mSubtitleTextView.getParent() != null) {
            removeView(mSubtitleTextView);
        }
        if (mSubtitleTextView != null) {
            mSubtitleTextView.setText(subtitle);
        }
        mSubtitleText = subtitle;
    
public voidsetSubtitleTextAppearance(android.content.Context context, int resId)
Sets the text color, size, style, hint color, and highlight color from the specified TextAppearance resource.

        mSubtitleTextAppearance = resId;
        if (mSubtitleTextView != null) {
            mSubtitleTextView.setTextAppearance(context, resId);
        }
    
public voidsetSubtitleTextColor(int color)
Sets the text color of the subtitle, if present.

param
color The new text color in 0xAARRGGBB format

        mSubtitleTextColor = color;
        if (mSubtitleTextView != null) {
            mSubtitleTextView.setTextColor(color);
        }
    
public voidsetTitle(int resId)
Set the title of this toolbar.

A title should be used as the anchor for a section of content. It should describe or name the content being viewed.

param
resId Resource ID of a string to set as the title

        setTitle(getContext().getText(resId));
    
public voidsetTitle(java.lang.CharSequence title)
Set the title of this toolbar.

A title should be used as the anchor for a section of content. It should describe or name the content being viewed.

param
title Title to set

        if (!TextUtils.isEmpty(title)) {
            if (mTitleTextView == null) {
                final Context context = getContext();
                mTitleTextView = new TextView(context);
                mTitleTextView.setSingleLine();
                mTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
                if (mTitleTextAppearance != 0) {
                    mTitleTextView.setTextAppearance(context, mTitleTextAppearance);
                }
                if (mTitleTextColor != 0) {
                    mTitleTextView.setTextColor(mTitleTextColor);
                }
            }
            if (mTitleTextView.getParent() == null) {
                addSystemView(mTitleTextView);
                updateChildVisibilityForExpandedActionView(mTitleTextView);
            }
        } else if (mTitleTextView != null && mTitleTextView.getParent() != null) {
            removeView(mTitleTextView);
        }
        if (mTitleTextView != null) {
            mTitleTextView.setText(title);
        }
        mTitleText = title;
    
public voidsetTitleTextAppearance(android.content.Context context, int resId)
Sets the text color, size, style, hint color, and highlight color from the specified TextAppearance resource.

        mTitleTextAppearance = resId;
        if (mTitleTextView != null) {
            mTitleTextView.setTextAppearance(context, resId);
        }
    
public voidsetTitleTextColor(int color)
Sets the text color of the title, if present.

param
color The new text color in 0xAARRGGBB format

        mTitleTextColor = color;
        if (mTitleTextView != null) {
            mTitleTextView.setTextColor(color);
        }
    
private booleanshouldCollapse()
Returns true if the Toolbar is collapsible and has no child views with a measured size > 0.

        if (!mCollapsible) return false;

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            if (shouldLayout(child) && child.getMeasuredWidth() > 0 &&
                    child.getMeasuredHeight() > 0) {
                return false;
            }
        }
        return true;
    
private booleanshouldLayout(android.view.View view)

        return view != null && view.getParent() == this && view.getVisibility() != GONE;
    
public booleanshowOverflowMenu()
Show the overflow items from the associated menu.

return
true if the menu was able to be shown, false otherwise

        return mMenuView != null && mMenuView.showOverflowMenu();
    
private static android.content.ContextthemifyContext(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr)
Allows us to emulate the {@code android:theme} attribute for devices before L.

        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Toolbar,
                defStyleAttr, 0);
        final int themeId = a.getResourceId(R.styleable.Toolbar_theme, 0);
        if (themeId != 0) {
            context = new ContextThemeWrapper(context, themeId);
        }
        a.recycle();
        return context;
    
private voidupdateChildVisibilityForExpandedActionView(android.view.View child)

        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
        if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
            child.setVisibility(mExpandedActionView != null ? GONE : VISIBLE);
        }