Toolbar.java revision a41b78973db3dfde159f7d641f794f462ad323d3
1e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell/*
2e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * Copyright (C) 2014 The Android Open Source Project
3e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *
4e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * you may not use this file except in compliance with the License.
6e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * You may obtain a copy of the License at
7e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *
8e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *
10e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * Unless required by applicable law or agreed to in writing, software
11e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * See the License for the specific language governing permissions and
14e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * limitations under the License.
15e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell */
16e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
17e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellpackage android.widget;
18e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1980756e38882720860db52f1fcc21fa1505a02abfTor Norbyeimport android.annotation.ColorInt;
20417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbyeimport android.annotation.DrawableRes;
21417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbyeimport android.annotation.MenuRes;
22e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.annotation.NonNull;
23e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viveretteimport android.annotation.Nullable;
24417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbyeimport android.annotation.StringRes;
25417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbyeimport android.annotation.StyleRes;
26e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport android.app.ActionBar;
27e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.content.Context;
28e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.content.res.TypedArray;
29a41b78973db3dfde159f7d641f794f462ad323d3Chris Banesimport android.graphics.RectF;
30e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.graphics.drawable.Drawable;
31e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.os.Parcel;
32e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.os.Parcelable;
33e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport android.text.Layout;
34e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.text.TextUtils;
35e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.util.AttributeSet;
36e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport android.view.CollapsibleActionView;
373d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viveretteimport android.view.ContextThemeWrapper;
38e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.view.Gravity;
39e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.view.Menu;
40e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.view.MenuInflater;
41e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.view.MenuItem;
4261d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powellimport android.view.MotionEvent;
43e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.view.View;
44e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport android.view.ViewGroup;
453d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette
46e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport com.android.internal.R;
47e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport com.android.internal.view.menu.MenuBuilder;
48e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport com.android.internal.view.menu.MenuItemImpl;
49e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport com.android.internal.view.menu.MenuPresenter;
50e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport com.android.internal.view.menu.MenuView;
51e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport com.android.internal.view.menu.SubMenuBuilder;
52e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport com.android.internal.widget.DecorToolbar;
53e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport com.android.internal.widget.ToolbarWidgetWrapper;
54e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
55e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport java.util.ArrayList;
56e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellimport java.util.List;
57e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
58e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell/**
59e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * A standard toolbar for use within application content.
60e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *
61e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * <p>A Toolbar is a generalization of {@link android.app.ActionBar action bars} for use
62e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * within application layouts. While an action bar is traditionally part of an
63e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * {@link android.app.Activity Activity's} opaque window decor controlled by the framework,
64e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * a Toolbar may be placed at any arbitrary level of nesting within a view hierarchy.
65e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * An application may choose to designate a Toolbar as the action bar for an Activity
66e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * using the {@link android.app.Activity#setActionBar(Toolbar) setActionBar()} method.</p>
67e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *
68e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * <p>Toolbar supports a more focused feature set than ActionBar. From start to end, a toolbar
69e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * may contain a combination of the following optional elements:
70e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *
71e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * <ul>
72e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     <li><em>A navigation button.</em> This may be an Up arrow, navigation menu toggle, close,
73e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     collapse, done or another glyph of the app's choosing. This button should always be used
74e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     to access other navigational destinations within the container of the Toolbar and
75157afde397f817e0a3a21c5d47011db462b6fff6Alan Viverette *     its signified content or otherwise leave the current context signified by the Toolbar.
76157afde397f817e0a3a21c5d47011db462b6fff6Alan Viverette *     The navigation button is vertically aligned within the Toolbar's
77157afde397f817e0a3a21c5d47011db462b6fff6Alan Viverette *     {@link android.R.styleable#View_minHeight minimum height}, if set.</li>
78e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     <li><em>A branded logo image.</em> This may extend to the height of the bar and can be
79e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     arbitrarily wide.</li>
80e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     <li><em>A title and subtitle.</em> The title should be a signpost for the Toolbar's current
81e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     position in the navigation hierarchy and the content contained there. The subtitle,
82e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     if present should indicate any extended information about the current content.
83e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     If an app uses a logo image it should strongly consider omitting a title and subtitle.</li>
84e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     <li><em>One or more custom views.</em> The application may add arbitrary child views
85e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     to the Toolbar. They will appear at this position within the layout. If a child view's
86e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     {@link LayoutParams} indicates a {@link Gravity} value of
87e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     {@link Gravity#CENTER_HORIZONTAL CENTER_HORIZONTAL} the view will attempt to center
88e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     within the available space remaining in the Toolbar after all other elements have been
89e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     measured.</li>
90e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     <li><em>An {@link ActionMenuView action menu}.</em> The menu of actions will pin to the
91e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     end of the Toolbar offering a few
92e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *     <a href="http://developer.android.com/design/patterns/actionbar.html#ActionButtons">
93157afde397f817e0a3a21c5d47011db462b6fff6Alan Viverette *     frequent, important or typical</a> actions along with an optional overflow menu for
94157afde397f817e0a3a21c5d47011db462b6fff6Alan Viverette *     additional actions. Action buttons are vertically aligned within the Toolbar's
95157afde397f817e0a3a21c5d47011db462b6fff6Alan Viverette *     {@link android.R.styleable#View_minHeight minimum height}, if set.</li>
96e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * </ul>
97e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * </p>
98e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell *
99e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * <p>In modern Android UIs developers should lean more on a visually distinct color scheme for
100e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * toolbars than on their application icon. The use of application icon plus title as a standard
101e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell * layout is discouraged on API 21 devices and newer.</p>
102e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell */
103e43340c80dc66c45edc793ecd0343774aa34d108Adam Powellpublic class Toolbar extends ViewGroup {
104e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private static final String TAG = "Toolbar";
105e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
106e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private ActionMenuView mMenuView;
107e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private TextView mTitleTextView;
108e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private TextView mSubtitleTextView;
109e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private ImageButton mNavButtonView;
110e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private ImageView mLogoView;
111e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
112e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private Drawable mCollapseIcon;
11385085343b378f00a34448b69e582226fa584b005Alan Viverette    private CharSequence mCollapseDescription;
114e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private ImageButton mCollapseButtonView;
115e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    View mExpandedActionView;
116e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1173d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette    /** Context against which to inflate popup menus. */
1183d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette    private Context mPopupContext;
1193d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette
1203d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette    /** Theme resource against which to inflate popup menus. */
1213d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette    private int mPopupTheme;
1223d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette
123e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int mTitleTextAppearance;
124e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int mSubtitleTextAppearance;
125e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private int mNavButtonStyle;
126e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
127e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private int mButtonGravity;
128e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
129e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private int mMaxButtonHeight;
13076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
131e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int mTitleMarginStart;
132e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int mTitleMarginEnd;
133e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int mTitleMarginTop;
134e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int mTitleMarginBottom;
135e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
13676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    private final RtlSpacingHelper mContentInsets = new RtlSpacingHelper();
13776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
138e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int mGravity = Gravity.START | Gravity.CENTER_VERTICAL;
139e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
140e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private CharSequence mTitleText;
141e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private CharSequence mSubtitleText;
142e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1431a264ce3d915b187b71101436bec3328c76288b0Adam Powell    private int mTitleTextColor;
1441a264ce3d915b187b71101436bec3328c76288b0Adam Powell    private int mSubtitleTextColor;
1451a264ce3d915b187b71101436bec3328c76288b0Adam Powell
14661d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell    private boolean mEatingTouch;
14761d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell
148e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    // Clear me after use.
149e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private final ArrayList<View> mTempViews = new ArrayList<View>();
150e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1517a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell    private final int[] mTempMargins = new int[2];
1527a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell
153e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private OnMenuItemClickListener mOnMenuItemClickListener;
154e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
155e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private final ActionMenuView.OnMenuItemClickListener mMenuViewItemClickListener =
156e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            new ActionMenuView.OnMenuItemClickListener() {
157e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                @Override
158e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                public boolean onMenuItemClick(MenuItem item) {
159e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    if (mOnMenuItemClickListener != null) {
160e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                        return mOnMenuItemClickListener.onMenuItemClick(item);
161e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    }
162e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    return false;
163e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                }
164e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            };
165e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
166e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private ToolbarWidgetWrapper mWrapper;
167e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private ActionMenuPresenter mOuterActionMenuPresenter;
168e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
16904c0d4607897157f01c908475fa0c6d7301cf7e5Adam Powell    private MenuPresenter.Callback mActionMenuPresenterCallback;
170c46125042493e66f7dfdccec24e3b0739600b194Adam Powell    private MenuBuilder.Callback mMenuBuilderCallback;
171e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
172360c1d89227570510de7bb11195c986300488464Adam Powell    private boolean mCollapsible;
173360c1d89227570510de7bb11195c986300488464Adam Powell
17431c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell    private final Runnable mShowOverflowMenuRunnable = new Runnable() {
17531c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        @Override public void run() {
17631c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            showOverflowMenu();
17731c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        }
17831c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell    };
17931c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
180e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public Toolbar(Context context) {
181e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        this(context, null);
182e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
183e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
184e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public Toolbar(Context context, AttributeSet attrs) {
185e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        this(context, attrs, com.android.internal.R.attr.toolbarStyle);
186e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
187e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
188e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public Toolbar(Context context, AttributeSet attrs, int defStyleAttr) {
189e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        this(context, attrs, defStyleAttr, 0);
190e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
191e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
192e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public Toolbar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
193e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        super(context, attrs, defStyleAttr, defStyleRes);
194e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
195e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Toolbar,
196e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                defStyleAttr, defStyleRes);
197e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
198e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        mTitleTextAppearance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance, 0);
199e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        mSubtitleTextAppearance = a.getResourceId(R.styleable.Toolbar_subtitleTextAppearance, 0);
200e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mNavButtonStyle = a.getResourceId(R.styleable.Toolbar_navigationButtonStyle, 0);
201e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        mGravity = a.getInteger(R.styleable.Toolbar_gravity, mGravity);
202e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mButtonGravity = a.getInteger(R.styleable.Toolbar_buttonGravity, Gravity.TOP);
20376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        mTitleMarginStart = mTitleMarginEnd = mTitleMarginTop = mTitleMarginBottom =
20476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell                a.getDimensionPixelOffset(R.styleable.Toolbar_titleMargins, 0);
205e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
206e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int marginStart = a.getDimensionPixelOffset(R.styleable.Toolbar_titleMarginStart, -1);
207e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (marginStart >= 0) {
208e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mTitleMarginStart = marginStart;
209e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
210e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
211e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int marginEnd = a.getDimensionPixelOffset(R.styleable.Toolbar_titleMarginEnd, -1);
212e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (marginEnd >= 0) {
213e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mTitleMarginEnd = marginEnd;
214e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
215e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
216e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int marginTop = a.getDimensionPixelOffset(R.styleable.Toolbar_titleMarginTop, -1);
217e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (marginTop >= 0) {
218e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mTitleMarginTop = marginTop;
219e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
220e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
221e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int marginBottom = a.getDimensionPixelOffset(R.styleable.Toolbar_titleMarginBottom,
222e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                -1);
223e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (marginBottom >= 0) {
224e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mTitleMarginBottom = marginBottom;
225e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
226e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
227e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mMaxButtonHeight = a.getDimensionPixelSize(R.styleable.Toolbar_maxButtonHeight, -1);
228e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
22976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        final int contentInsetStart =
23076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell                a.getDimensionPixelOffset(R.styleable.Toolbar_contentInsetStart,
23176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell                        RtlSpacingHelper.UNDEFINED);
23276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        final int contentInsetEnd =
23376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell                a.getDimensionPixelOffset(R.styleable.Toolbar_contentInsetEnd,
23476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell                        RtlSpacingHelper.UNDEFINED);
23576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        final int contentInsetLeft =
23676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell                a.getDimensionPixelSize(R.styleable.Toolbar_contentInsetLeft, 0);
23776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        final int contentInsetRight =
23876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell                a.getDimensionPixelSize(R.styleable.Toolbar_contentInsetRight, 0);
23976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
24076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        mContentInsets.setAbsolute(contentInsetLeft, contentInsetRight);
24176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
24276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        if (contentInsetStart != RtlSpacingHelper.UNDEFINED ||
24376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell                contentInsetEnd != RtlSpacingHelper.UNDEFINED) {
24476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell            mContentInsets.setRelative(contentInsetStart, contentInsetEnd);
24576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        }
24676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
247e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mCollapseIcon = a.getDrawable(R.styleable.Toolbar_collapseIcon);
24885085343b378f00a34448b69e582226fa584b005Alan Viverette        mCollapseDescription = a.getText(R.styleable.Toolbar_collapseContentDescription);
249e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
250e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final CharSequence title = a.getText(R.styleable.Toolbar_title);
251e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (!TextUtils.isEmpty(title)) {
252e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            setTitle(title);
253e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
254e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
255e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final CharSequence subtitle = a.getText(R.styleable.Toolbar_subtitle);
256e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (!TextUtils.isEmpty(subtitle)) {
25707a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell            setSubtitle(subtitle);
258e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
2593d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette
26077e5037d8125b94e524264dc1890ab9b6b7df0afAlan Viverette        // Set the default context, since setPopupTheme() may be a no-op.
26177e5037d8125b94e524264dc1890ab9b6b7df0afAlan Viverette        mPopupContext = mContext;
26222a117d1b60869ed36d125796396f190b4b002fbAlan Viverette        setPopupTheme(a.getResourceId(R.styleable.Toolbar_popupTheme, 0));
2637c13bc2a7090544a04fc93813794a8b97bc86ff7Adam Powell
2647c13bc2a7090544a04fc93813794a8b97bc86ff7Adam Powell        final Drawable navIcon = a.getDrawable(R.styleable.Toolbar_navigationIcon);
2657c13bc2a7090544a04fc93813794a8b97bc86ff7Adam Powell        if (navIcon != null) {
2667c13bc2a7090544a04fc93813794a8b97bc86ff7Adam Powell            setNavigationIcon(navIcon);
26712b0321c0b400f105cad40568a1f572020ba6336Adam Powell        }
26812b0321c0b400f105cad40568a1f572020ba6336Adam Powell
26912b0321c0b400f105cad40568a1f572020ba6336Adam Powell        final CharSequence navDesc = a.getText(
27012b0321c0b400f105cad40568a1f572020ba6336Adam Powell                R.styleable.Toolbar_navigationContentDescription);
27112b0321c0b400f105cad40568a1f572020ba6336Adam Powell        if (!TextUtils.isEmpty(navDesc)) {
27212b0321c0b400f105cad40568a1f572020ba6336Adam Powell            setNavigationContentDescription(navDesc);
2737c13bc2a7090544a04fc93813794a8b97bc86ff7Adam Powell        }
27422a117d1b60869ed36d125796396f190b4b002fbAlan Viverette        a.recycle();
2753d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette    }
2763d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette
2773d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette    /**
2783d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     * Specifies the theme to use when inflating popup menus. By default, uses
2793d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     * the same theme as the toolbar itself.
2803d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     *
2813d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     * @param resId theme used to inflate popup menus
2823d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     * @see #getPopupTheme()
2833d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     */
284417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void setPopupTheme(@StyleRes int resId) {
2853d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette        if (mPopupTheme != resId) {
2863d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            mPopupTheme = resId;
2873d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            if (resId == 0) {
2883d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette                mPopupContext = mContext;
2893d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            } else {
2903d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette                mPopupContext = new ContextThemeWrapper(mContext, resId);
2913d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            }
2923d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette        }
2933d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette    }
2943d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette
2953d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette    /**
2963d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     * @return resource identifier of the theme used to inflate popup menus, or
2973d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     *         0 if menus are inflated against the toolbar theme
2983d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     * @see #setPopupTheme(int)
2993d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette     */
3003d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette    public int getPopupTheme() {
3013d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette        return mPopupTheme;
302e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
303e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
30476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    @Override
30576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    public void onRtlPropertiesChanged(@ResolvedLayoutDir int layoutDirection) {
30676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        super.onRtlPropertiesChanged(layoutDirection);
30776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        mContentInsets.setDirection(layoutDirection == LAYOUT_DIRECTION_RTL);
30876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    }
30976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
310e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
311e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set a logo drawable from a resource id.
312e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
313e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>This drawable should generally take the place of title text. The logo cannot be
314e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * clicked. Apps using a logo should also supply a description using
315e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * {@link #setLogoDescription(int)}.</p>
316e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
317e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param resId ID of a drawable resource
318e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
319417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void setLogo(@DrawableRes int resId) {
320e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        setLogo(getContext().getDrawable(resId));
321e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
322e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
323e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /** @hide */
324e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public boolean canShowOverflowMenu() {
325e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return getVisibility() == VISIBLE && mMenuView != null && mMenuView.isOverflowReserved();
326e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
327e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
328e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /**
329e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * Check whether the overflow menu is currently showing. This may not reflect
330e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * a pending show operation in progress.
331e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     *
332e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * @return true if the overflow menu is currently showing
333e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     */
334e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public boolean isOverflowMenuShowing() {
335e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mMenuView != null && mMenuView.isOverflowMenuShowing();
336e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
337e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
338e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /** @hide */
339e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public boolean isOverflowMenuShowPending() {
340e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mMenuView != null && mMenuView.isOverflowMenuShowPending();
341e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
342e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
343e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /**
344e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * Show the overflow items from the associated menu.
345e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     *
346e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * @return true if the menu was able to be shown, false otherwise
347e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     */
348e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public boolean showOverflowMenu() {
349e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mMenuView != null && mMenuView.showOverflowMenu();
350e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
351e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
352e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /**
353e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * Hide the overflow items from the associated menu.
354e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     *
355e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * @return true if the menu was able to be hidden, false otherwise
356e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     */
357e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public boolean hideOverflowMenu() {
358e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mMenuView != null && mMenuView.hideOverflowMenu();
359e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
360e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
361e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /** @hide */
362e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public void setMenu(MenuBuilder menu, ActionMenuPresenter outerPresenter) {
363e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (menu == null && mMenuView == null) {
364e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return;
365e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
366e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
367e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        ensureMenuView();
368e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        final MenuBuilder oldMenu = mMenuView.peekMenu();
369e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (oldMenu == menu) {
370e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return;
371e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
372e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
373e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (oldMenu != null) {
374e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            oldMenu.removeMenuPresenter(mOuterActionMenuPresenter);
375e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            oldMenu.removeMenuPresenter(mExpandedMenuPresenter);
376e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
377e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
378e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (mExpandedMenuPresenter == null) {
379e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
380e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
381e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
382e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        outerPresenter.setExpandedActionViewsExclusive(true);
383e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (menu != null) {
3843d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            menu.addMenuPresenter(outerPresenter, mPopupContext);
3853d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            menu.addMenuPresenter(mExpandedMenuPresenter, mPopupContext);
386e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        } else {
3873d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            outerPresenter.initForMenu(mPopupContext, null);
3883d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            mExpandedMenuPresenter.initForMenu(mPopupContext, null);
389e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            outerPresenter.updateMenuView(true);
390e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mExpandedMenuPresenter.updateMenuView(true);
391e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
3923d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette        mMenuView.setPopupTheme(mPopupTheme);
393e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mMenuView.setPresenter(outerPresenter);
394e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mOuterActionMenuPresenter = outerPresenter;
395e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
396e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
397e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /**
398e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * Dismiss all currently showing popup menus, including overflow or submenus.
399e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     */
400e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public void dismissPopupMenus() {
401e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (mMenuView != null) {
402e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mMenuView.dismissPopupMenus();
403e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
404e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
405e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
406e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /** @hide */
407e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public boolean isTitleTruncated() {
408e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (mTitleTextView == null) {
409e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return false;
410e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
411e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
412e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        final Layout titleLayout = mTitleTextView.getLayout();
413e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (titleLayout == null) {
414e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return false;
415e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
416e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
417e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        final int lineCount = titleLayout.getLineCount();
418e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        for (int i = 0; i < lineCount; i++) {
419e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (titleLayout.getEllipsisCount(i) > 0) {
420e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                return true;
421e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
422e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
423e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return false;
424e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
425e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
426e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
427e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set a logo drawable.
428e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
429e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>This drawable should generally take the place of title text. The logo cannot be
430e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * clicked. Apps using a logo should also supply a description using
431e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * {@link #setLogoDescription(int)}.</p>
432e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
433e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param drawable Drawable to use as a logo
434e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
435e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public void setLogo(Drawable drawable) {
436e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (drawable != null) {
437e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            ensureLogoView();
438e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (mLogoView.getParent() == null) {
439e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                addSystemView(mLogoView);
44031c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell                updateChildVisibilityForExpandedActionView(mLogoView);
441e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
442e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        } else if (mLogoView != null && mLogoView.getParent() != null) {
443e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            removeView(mLogoView);
444e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
445e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (mLogoView != null) {
446e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mLogoView.setImageDrawable(drawable);
447e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
448e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
449e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
450e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
451e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Return the current logo drawable.
452e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
453e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @return The current logo drawable
454e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @see #setLogo(int)
455e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @see #setLogo(android.graphics.drawable.Drawable)
456e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
457e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public Drawable getLogo() {
458e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return mLogoView != null ? mLogoView.getDrawable() : null;
459e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
460e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
461e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
462e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set a description of the toolbar's logo.
463e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
464e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>This description will be used for accessibility or other similar descriptions
465e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * of the UI.</p>
466e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
467e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param resId String resource id
468e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
469417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void setLogoDescription(@StringRes int resId) {
470e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        setLogoDescription(getContext().getText(resId));
471e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
472e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
473e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
474e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set a description of the toolbar's logo.
475e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
476e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>This description will be used for accessibility or other similar descriptions
477e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * of the UI.</p>
478e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
479e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param description Description to set
480e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
481e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public void setLogoDescription(CharSequence description) {
482e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (!TextUtils.isEmpty(description)) {
483e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            ensureLogoView();
484e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
485e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (mLogoView != null) {
486e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mLogoView.setContentDescription(description);
487e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
488e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
489e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
490e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
491e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Return the description of the toolbar's logo.
492e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
493e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @return A description of the logo
494e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
495e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public CharSequence getLogoDescription() {
496e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return mLogoView != null ? mLogoView.getContentDescription() : null;
497e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
498e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
499e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private void ensureLogoView() {
500e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (mLogoView == null) {
501e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mLogoView = new ImageView(getContext());
502e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
503e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
504e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
505e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
506e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * Check whether this Toolbar is currently hosting an expanded action view.
507e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
508e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * <p>An action view may be expanded either directly from the
509e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * {@link android.view.MenuItem MenuItem} it belongs to or by user action. If the Toolbar
510e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * has an expanded action view it can be collapsed using the {@link #collapseActionView()}
511e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * method.</p>
512e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     *
513e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * @return true if the Toolbar has an expanded action view
514e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     */
515e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public boolean hasExpandedActionView() {
516e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mExpandedMenuPresenter != null &&
517e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mExpandedMenuPresenter.mCurrentExpandedItem != null;
518e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
519e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
520e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /**
521e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * Collapse a currently expanded action view. If this Toolbar does not have an
522e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * expanded action view this method has no effect.
523e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     *
524e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * <p>An action view may be expanded either directly from the
525e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * {@link android.view.MenuItem MenuItem} it belongs to or by user action.</p>
526e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     *
527e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * @see #hasExpandedActionView()
528e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     */
529e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public void collapseActionView() {
530e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
531e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mExpandedMenuPresenter.mCurrentExpandedItem;
532e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (item != null) {
533e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            item.collapseActionView();
534e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
535e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
536e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
537e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /**
538e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * Returns the title of this toolbar.
539e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     *
540e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * @return The current title.
541e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
542e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public CharSequence getTitle() {
543e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return mTitleText;
544e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
545e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
546e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
547e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set the title of this toolbar.
548e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
549e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>A title should be used as the anchor for a section of content. It should
550e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * describe or name the content being viewed.</p>
551e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
552e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param resId Resource ID of a string to set as the title
553e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
554417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void setTitle(@StringRes int resId) {
555e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        setTitle(getContext().getText(resId));
556e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
557e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
558e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
559e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set the title of this toolbar.
560e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
561e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>A title should be used as the anchor for a section of content. It should
562e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * describe or name the content being viewed.</p>
563e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
564e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param title Title to set
565e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
566e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public void setTitle(CharSequence title) {
567e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (!TextUtils.isEmpty(title)) {
568e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (mTitleTextView == null) {
569e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final Context context = getContext();
570e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                mTitleTextView = new TextView(context);
571e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mTitleTextView.setSingleLine();
572e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
5731a264ce3d915b187b71101436bec3328c76288b0Adam Powell                if (mTitleTextAppearance != 0) {
574bb98ebd6b15f4cf942b156892988801c95601f2fAlan Viverette                    mTitleTextView.setTextAppearance(mTitleTextAppearance);
5751a264ce3d915b187b71101436bec3328c76288b0Adam Powell                }
5761a264ce3d915b187b71101436bec3328c76288b0Adam Powell                if (mTitleTextColor != 0) {
5771a264ce3d915b187b71101436bec3328c76288b0Adam Powell                    mTitleTextView.setTextColor(mTitleTextColor);
5781a264ce3d915b187b71101436bec3328c76288b0Adam Powell                }
579e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
580e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (mTitleTextView.getParent() == null) {
581e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                addSystemView(mTitleTextView);
58231c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell                updateChildVisibilityForExpandedActionView(mTitleTextView);
583e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
584e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        } else if (mTitleTextView != null && mTitleTextView.getParent() != null) {
585e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            removeView(mTitleTextView);
586e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
587e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (mTitleTextView != null) {
588e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mTitleTextView.setText(title);
589e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
590e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        mTitleText = title;
591e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
592e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
593e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
594e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Return the subtitle of this toolbar.
595e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
596e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @return The current subtitle
597e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
598e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public CharSequence getSubtitle() {
599e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return mSubtitleText;
600e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
601e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
602e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
603e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set the subtitle of this toolbar.
604e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
605e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>Subtitles should express extended information about the current content.</p>
606e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
607e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param resId String resource ID
608e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
609417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void setSubtitle(@StringRes int resId) {
610e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        setSubtitle(getContext().getText(resId));
611e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
612e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
613e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
614e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set the subtitle of this toolbar.
615e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
616e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>Subtitles should express extended information about the current content.</p>
617e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
618e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param subtitle Subtitle to set
619e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
620e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public void setSubtitle(CharSequence subtitle) {
621e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (!TextUtils.isEmpty(subtitle)) {
622e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (mSubtitleTextView == null) {
623e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final Context context = getContext();
624e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                mSubtitleTextView = new TextView(context);
625e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mSubtitleTextView.setSingleLine();
626e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mSubtitleTextView.setEllipsize(TextUtils.TruncateAt.END);
6271a264ce3d915b187b71101436bec3328c76288b0Adam Powell                if (mSubtitleTextAppearance != 0) {
628bb98ebd6b15f4cf942b156892988801c95601f2fAlan Viverette                    mSubtitleTextView.setTextAppearance(mSubtitleTextAppearance);
6291a264ce3d915b187b71101436bec3328c76288b0Adam Powell                }
6301a264ce3d915b187b71101436bec3328c76288b0Adam Powell                if (mSubtitleTextColor != 0) {
6311a264ce3d915b187b71101436bec3328c76288b0Adam Powell                    mSubtitleTextView.setTextColor(mSubtitleTextColor);
6321a264ce3d915b187b71101436bec3328c76288b0Adam Powell                }
633e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
634e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (mSubtitleTextView.getParent() == null) {
635e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                addSystemView(mSubtitleTextView);
63631c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell                updateChildVisibilityForExpandedActionView(mSubtitleTextView);
637e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
638e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        } else if (mSubtitleTextView != null && mSubtitleTextView.getParent() != null) {
639e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            removeView(mSubtitleTextView);
640e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
641e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (mSubtitleTextView != null) {
642e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mSubtitleTextView.setText(subtitle);
643e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
644e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        mSubtitleText = subtitle;
645e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
646e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
647e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
648ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell     * Sets the text color, size, style, hint color, and highlight color
649ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell     * from the specified TextAppearance resource.
650ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell     */
651417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void setTitleTextAppearance(Context context, @StyleRes int resId) {
652ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell        mTitleTextAppearance = resId;
653ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell        if (mTitleTextView != null) {
654bb98ebd6b15f4cf942b156892988801c95601f2fAlan Viverette            mTitleTextView.setTextAppearance(resId);
655ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell        }
656ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell    }
657ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell
658ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell    /**
659ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell     * Sets the text color, size, style, hint color, and highlight color
660ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell     * from the specified TextAppearance resource.
661ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell     */
662417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void setSubtitleTextAppearance(Context context, @StyleRes int resId) {
663ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell        mSubtitleTextAppearance = resId;
664ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell        if (mSubtitleTextView != null) {
665bb98ebd6b15f4cf942b156892988801c95601f2fAlan Viverette            mSubtitleTextView.setTextAppearance(resId);
666ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell        }
667ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell    }
668ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell
669ebba5d4edd763b19124b715a0f084d2f00c84a47Adam Powell    /**
6701a264ce3d915b187b71101436bec3328c76288b0Adam Powell     * Sets the text color of the title, if present.
6711a264ce3d915b187b71101436bec3328c76288b0Adam Powell     *
6721a264ce3d915b187b71101436bec3328c76288b0Adam Powell     * @param color The new text color in 0xAARRGGBB format
6731a264ce3d915b187b71101436bec3328c76288b0Adam Powell     */
67480756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void setTitleTextColor(@ColorInt int color) {
6751a264ce3d915b187b71101436bec3328c76288b0Adam Powell        mTitleTextColor = color;
6761a264ce3d915b187b71101436bec3328c76288b0Adam Powell        if (mTitleTextView != null) {
6771a264ce3d915b187b71101436bec3328c76288b0Adam Powell            mTitleTextView.setTextColor(color);
6781a264ce3d915b187b71101436bec3328c76288b0Adam Powell        }
6791a264ce3d915b187b71101436bec3328c76288b0Adam Powell    }
6801a264ce3d915b187b71101436bec3328c76288b0Adam Powell
6811a264ce3d915b187b71101436bec3328c76288b0Adam Powell    /**
6821a264ce3d915b187b71101436bec3328c76288b0Adam Powell     * Sets the text color of the subtitle, if present.
6831a264ce3d915b187b71101436bec3328c76288b0Adam Powell     *
6841a264ce3d915b187b71101436bec3328c76288b0Adam Powell     * @param color The new text color in 0xAARRGGBB format
6851a264ce3d915b187b71101436bec3328c76288b0Adam Powell     */
68680756e38882720860db52f1fcc21fa1505a02abfTor Norbye    public void setSubtitleTextColor(@ColorInt int color) {
6871a264ce3d915b187b71101436bec3328c76288b0Adam Powell        mSubtitleTextColor = color;
6881a264ce3d915b187b71101436bec3328c76288b0Adam Powell        if (mSubtitleTextView != null) {
6891a264ce3d915b187b71101436bec3328c76288b0Adam Powell            mSubtitleTextView.setTextColor(color);
6901a264ce3d915b187b71101436bec3328c76288b0Adam Powell        }
6911a264ce3d915b187b71101436bec3328c76288b0Adam Powell    }
6921a264ce3d915b187b71101436bec3328c76288b0Adam Powell
6931a264ce3d915b187b71101436bec3328c76288b0Adam Powell    /**
6947901b2a54981b769bf27852c41ce612871a8e019Adam Powell     * Retrieve the currently configured content description for the navigation button view.
6957901b2a54981b769bf27852c41ce612871a8e019Adam Powell     * This will be used to describe the navigation action to users through mechanisms such
6967901b2a54981b769bf27852c41ce612871a8e019Adam Powell     * as screen readers or tooltips.
6977901b2a54981b769bf27852c41ce612871a8e019Adam Powell     *
6987901b2a54981b769bf27852c41ce612871a8e019Adam Powell     * @return The navigation button's content description
699d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     *
700d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     * @attr ref android.R.styleable#Toolbar_navigationContentDescription
7017901b2a54981b769bf27852c41ce612871a8e019Adam Powell     */
702e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette    @Nullable
7037901b2a54981b769bf27852c41ce612871a8e019Adam Powell    public CharSequence getNavigationContentDescription() {
7047901b2a54981b769bf27852c41ce612871a8e019Adam Powell        return mNavButtonView != null ? mNavButtonView.getContentDescription() : null;
7057901b2a54981b769bf27852c41ce612871a8e019Adam Powell    }
7067901b2a54981b769bf27852c41ce612871a8e019Adam Powell
7077901b2a54981b769bf27852c41ce612871a8e019Adam Powell    /**
708e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * Set a content description for the navigation button if one is present. The content
709e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * description will be read via screen readers or other accessibility systems to explain
710e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * the action of the navigation button.
711e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     *
712e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * @param resId Resource ID of a content description string to set, or 0 to
713e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     *              clear the description
714d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     *
715d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     * @attr ref android.R.styleable#Toolbar_navigationContentDescription
716e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     */
717417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void setNavigationContentDescription(@StringRes int resId) {
718e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette        setNavigationContentDescription(resId != 0 ? getContext().getText(resId) : null);
719e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
720e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
721e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /**
722e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * Set a content description for the navigation button if one is present. The content
723e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * description will be read via screen readers or other accessibility systems to explain
724e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     * the action of the navigation button.
725e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     *
726e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * @param description Content description to set, or <code>null</code> to
727e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     *                    clear the content description
728d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     *
729d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     * @attr ref android.R.styleable#Toolbar_navigationContentDescription
730e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell     */
731e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette    public void setNavigationContentDescription(@Nullable CharSequence description) {
732e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette        if (!TextUtils.isEmpty(description)) {
733e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette            ensureNavButtonView();
734e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette        }
735e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette        if (mNavButtonView != null) {
736e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette            mNavButtonView.setContentDescription(description);
737e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette        }
738e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette    }
739e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette
740e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette    /**
741e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * Set the icon to use for the toolbar's navigation button.
742e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     *
743e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * <p>The navigation button appears at the start of the toolbar if present. Setting an icon
744e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * will make the navigation button visible.</p>
745e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     *
746e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * <p>If you use a navigation icon you should also set a description for its action using
747e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * {@link #setNavigationContentDescription(int)}. This is used for accessibility and
748e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * tooltips.</p>
749e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     *
750e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * @param resId Resource ID of a drawable to set
751d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     *
752d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     * @attr ref android.R.styleable#Toolbar_navigationIcon
753e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     */
754417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void setNavigationIcon(@DrawableRes int resId) {
755e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette        setNavigationIcon(getContext().getDrawable(resId));
756e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
757e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
758e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /**
759e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set the icon to use for the toolbar's navigation button.
760e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
761e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>The navigation button appears at the start of the toolbar if present. Setting an icon
762e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * will make the navigation button visible.</p>
763e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
764e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>If you use a navigation icon you should also set a description for its action using
765e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * {@link #setNavigationContentDescription(int)}. This is used for accessibility and
766e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * tooltips.</p>
767e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
768e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette     * @param icon Drawable to set, may be null to clear the icon
769d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     *
770d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     * @attr ref android.R.styleable#Toolbar_navigationIcon
771e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
772e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette    public void setNavigationIcon(@Nullable Drawable icon) {
773e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (icon != null) {
774e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            ensureNavButtonView();
775e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (mNavButtonView.getParent() == null) {
776e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                addSystemView(mNavButtonView);
77731c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell                updateChildVisibilityForExpandedActionView(mNavButtonView);
778e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
779e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        } else if (mNavButtonView != null && mNavButtonView.getParent() != null) {
780e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            removeView(mNavButtonView);
781e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
782e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (mNavButtonView != null) {
783e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mNavButtonView.setImageDrawable(icon);
784e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
785e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
786e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
787e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
788e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Return the current drawable used as the navigation icon.
789e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
790e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @return The navigation icon drawable
791d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     *
792d760249623a57d35dc0b4e57972eb9a72934d500Adam Powell     * @attr ref android.R.styleable#Toolbar_navigationIcon
793e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
794e88700a2ad69e9b99824f2de3d8ba3d44054b24cAlan Viverette    @Nullable
795e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public Drawable getNavigationIcon() {
796e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return mNavButtonView != null ? mNavButtonView.getDrawable() : null;
797e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
798e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
799e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
800e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set a listener to respond to navigation events.
801e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
802e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>This listener will be called whenever the user clicks the navigation button
803e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * at the start of the toolbar. An icon must be set for the navigation button to appear.</p>
804e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
805e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param listener Listener to set
806e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @see #setNavigationIcon(android.graphics.drawable.Drawable)
807e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
808e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public void setNavigationOnClickListener(OnClickListener listener) {
809e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        ensureNavButtonView();
810e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        mNavButtonView.setOnClickListener(listener);
811e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
812e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
813e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
814a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes     * Return the Menu shown in the toolbar.
8159cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes     *
816a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes     * <p>Applications that wish to populate the toolbar's menu can do so from here. To use
817a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes     * an XML menu resource, use {@link #inflateMenu(int)}.</p>
8189cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes     *
819a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes     * @return The toolbar's Menu
8209cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes     */
821a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes    public Menu getMenu() {
822a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes        ensureMenu();
823a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes        return mMenuView.getMenu();
8249cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes    }
8259cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes
8269cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes    /**
827a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes     * Set the icon to use for the overflow button.
8289cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes     *
829a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes     * @param icon Drawable to set, may be null to clear the icon
8309cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes     */
831a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes    public void setOverflowIcon(@Nullable Drawable icon) {
832a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes        ensureMenu();
833a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes        mMenuView.setOverflowIcon(icon);
8349cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes    }
8359cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes
8369cc36ca1b520c06f882e84b909f3a2b75d303a06Chris Banes    /**
837a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes     * Return the current drawable used as the overflow icon.
838e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
839a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes     * @return The overflow icon drawable
840e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
841a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes    @Nullable
842a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes    public Drawable getOverflowIcon() {
84307a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell        ensureMenu();
844a41b78973db3dfde159f7d641f794f462ad323d3Chris Banes        return mMenuView.getOverflowIcon();
845e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
846e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
84707a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell    private void ensureMenu() {
84807a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell        ensureMenuView();
84907a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell        if (mMenuView.peekMenu() == null) {
85007a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell            // Initialize a new menu for the first time.
85107a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell            final MenuBuilder menu = (MenuBuilder) mMenuView.getMenu();
85207a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell            if (mExpandedMenuPresenter == null) {
85307a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell                mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
85407a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell            }
85507a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell            mMenuView.setExpandedActionViewsExclusive(true);
8563d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            menu.addMenuPresenter(mExpandedMenuPresenter, mPopupContext);
85707a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell        }
85807a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell    }
85907a74548ae5c1e064508cb1c79ac34de1142b240Adam Powell
860e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private void ensureMenuView() {
861e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (mMenuView == null) {
862e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mMenuView = new ActionMenuView(getContext());
8633d0f21dab8d891b9aebdd5277348d549eeb843e6Alan Viverette            mMenuView.setPopupTheme(mPopupTheme);
864e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            mMenuView.setOnMenuItemClickListener(mMenuViewItemClickListener);
865c46125042493e66f7dfdccec24e3b0739600b194Adam Powell            mMenuView.setMenuCallbacks(mActionMenuPresenterCallback, mMenuBuilderCallback);
866e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final LayoutParams lp = generateDefaultLayoutParams();
867e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            lp.gravity = Gravity.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
868e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mMenuView.setLayoutParams(lp);
869e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            addSystemView(mMenuView);
870e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
871e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
872e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
873e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private MenuInflater getMenuInflater() {
874e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return new MenuInflater(getContext());
875e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
876e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
877e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
878e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Inflate a menu resource into this toolbar.
879e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
880e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>Inflate an XML menu resource into this toolbar. Existing items in the menu will not
881e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * be modified or removed.</p>
882e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
883e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param resId ID of a menu resource to inflate
884e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
885417ee5ba89f7e0fe5efd34fce74bf1ee5923d976Tor Norbye    public void inflateMenu(@MenuRes int resId) {
886e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        getMenuInflater().inflate(resId, getMenu());
887e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
888e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
889e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
890e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Set a listener to respond to menu item click events.
891e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
892e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * <p>This listener will be invoked whenever a user selects a menu item from
893e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * the action buttons presented at the end of the toolbar or the associated overflow.</p>
894e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
895e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param listener Listener to set
896e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
897e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
898e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        mOnMenuItemClickListener = listener;
899e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
900e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
90176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    /**
90276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * Set the content insets for this toolbar relative to layout direction.
90376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
90476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * <p>The content inset affects the valid area for Toolbar content other than
90576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * the navigation button and menu. Insets define the minimum margin for these components
90676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * and can be used to effectively align Toolbar content along well-known gridlines.</p>
90776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
90876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @param contentInsetStart Content inset for the toolbar starting edge
90976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @param contentInsetEnd Content inset for the toolbar ending edge
91076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
91176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsAbsolute(int, int)
91276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetStart()
91376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetEnd()
91476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetLeft()
91576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetRight()
91676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     */
91776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    public void setContentInsetsRelative(int contentInsetStart, int contentInsetEnd) {
91876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        mContentInsets.setRelative(contentInsetStart, contentInsetEnd);
91976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    }
92076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
92176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    /**
92276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * Get the starting content inset for this toolbar.
92376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
92476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * <p>The content inset affects the valid area for Toolbar content other than
92576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * the navigation button and menu. Insets define the minimum margin for these components
92676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * and can be used to effectively align Toolbar content along well-known gridlines.</p>
92776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
92876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @return The starting content inset for this toolbar
92976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
93076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsRelative(int, int)
93176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsAbsolute(int, int)
93276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetEnd()
93376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetLeft()
93476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetRight()
93576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     */
93676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    public int getContentInsetStart() {
93776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        return mContentInsets.getStart();
93876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    }
93976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
94076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    /**
94176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * Get the ending content inset for this toolbar.
94276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
94376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * <p>The content inset affects the valid area for Toolbar content other than
94476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * the navigation button and menu. Insets define the minimum margin for these components
94576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * and can be used to effectively align Toolbar content along well-known gridlines.</p>
94676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
94776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @return The ending content inset for this toolbar
94876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
94976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsRelative(int, int)
95076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsAbsolute(int, int)
95176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetStart()
95276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetLeft()
95376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetRight()
95476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     */
95576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    public int getContentInsetEnd() {
95676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        return mContentInsets.getEnd();
95776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    }
95876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
95976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    /**
96076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * Set the content insets for this toolbar.
96176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
96276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * <p>The content inset affects the valid area for Toolbar content other than
96376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * the navigation button and menu. Insets define the minimum margin for these components
96476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * and can be used to effectively align Toolbar content along well-known gridlines.</p>
96576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
96676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @param contentInsetLeft Content inset for the toolbar's left edge
96776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @param contentInsetRight Content inset for the toolbar's right edge
96876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
96976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsAbsolute(int, int)
97076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetStart()
97176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetEnd()
97276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetLeft()
97376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetRight()
97476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     */
97576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    public void setContentInsetsAbsolute(int contentInsetLeft, int contentInsetRight) {
97676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        mContentInsets.setAbsolute(contentInsetLeft, contentInsetRight);
97776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    }
97876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
97976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    /**
98076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * Get the left content inset for this toolbar.
98176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
98276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * <p>The content inset affects the valid area for Toolbar content other than
98376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * the navigation button and menu. Insets define the minimum margin for these components
98476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * and can be used to effectively align Toolbar content along well-known gridlines.</p>
98576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
98676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @return The left content inset for this toolbar
98776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
98876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsRelative(int, int)
98976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsAbsolute(int, int)
99076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetStart()
99176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetEnd()
99276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetRight()
99376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     */
99476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    public int getContentInsetLeft() {
99576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        return mContentInsets.getLeft();
99676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    }
99776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
99876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    /**
99976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * Get the right content inset for this toolbar.
100076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
100176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * <p>The content inset affects the valid area for Toolbar content other than
100276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * the navigation button and menu. Insets define the minimum margin for these components
100376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * and can be used to effectively align Toolbar content along well-known gridlines.</p>
100476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
100576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @return The right content inset for this toolbar
100676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     *
100776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsRelative(int, int)
100876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #setContentInsetsAbsolute(int, int)
100976d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetStart()
101076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetEnd()
101176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     * @see #getContentInsetLeft()
101276d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell     */
101376d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    public int getContentInsetRight() {
101476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        return mContentInsets.getRight();
101576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell    }
101676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
1017e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private void ensureNavButtonView() {
1018e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (mNavButtonView == null) {
1019e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mNavButtonView = new ImageButton(getContext(), null, 0, mNavButtonStyle);
1020e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final LayoutParams lp = generateDefaultLayoutParams();
1021e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
1022e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mNavButtonView.setLayoutParams(lp);
1023e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1024e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
1025e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1026e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private void ensureCollapseButtonView() {
1027e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (mCollapseButtonView == null) {
1028e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mCollapseButtonView = new ImageButton(getContext(), null, 0, mNavButtonStyle);
1029e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mCollapseButtonView.setImageDrawable(mCollapseIcon);
103085085343b378f00a34448b69e582226fa584b005Alan Viverette            mCollapseButtonView.setContentDescription(mCollapseDescription);
1031e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final LayoutParams lp = generateDefaultLayoutParams();
1032e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
1033e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            lp.mViewType = LayoutParams.EXPANDED;
1034e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mCollapseButtonView.setLayoutParams(lp);
1035e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mCollapseButtonView.setOnClickListener(new OnClickListener() {
1036e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                @Override
1037e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                public void onClick(View v) {
1038e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    collapseActionView();
1039e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                }
1040e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            });
1041e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1042e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1043e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1044e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private void addSystemView(View v) {
1045e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        final ViewGroup.LayoutParams vlp = v.getLayoutParams();
1046e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        final LayoutParams lp;
1047e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        if (vlp == null) {
1048e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette            lp = generateDefaultLayoutParams();
1049e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        } else if (!checkLayoutParams(vlp)) {
1050e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette            lp = generateLayoutParams(vlp);
1051e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        } else {
1052e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette            lp = (LayoutParams) vlp;
1053e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        }
1054e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        lp.mViewType = LayoutParams.SYSTEM;
1055e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        addView(v, lp);
1056e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1057e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1058e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    @Override
1059e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    protected Parcelable onSaveInstanceState() {
1060e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        SavedState state = new SavedState(super.onSaveInstanceState());
106131c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
106231c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) {
106331c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId();
106431c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        }
106531c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
106631c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        state.isOverflowOpen = isOverflowMenuShowing();
106731c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
1068e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return state;
1069e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1070e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1071e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    @Override
1072e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    protected void onRestoreInstanceState(Parcelable state) {
1073e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final SavedState ss = (SavedState) state;
1074e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        super.onRestoreInstanceState(ss.getSuperState());
107531c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
107631c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        final Menu menu = mMenuView != null ? mMenuView.peekMenu() : null;
107731c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        if (ss.expandedMenuItemId != 0 && mExpandedMenuPresenter != null && menu != null) {
107831c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            final MenuItem item = menu.findItem(ss.expandedMenuItemId);
107931c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            if (item != null) {
108031c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell                item.expandActionView();
108131c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            }
108231c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        }
108331c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
108431c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        if (ss.isOverflowOpen) {
108531c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            postShowOverflowMenu();
108631c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        }
108731c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell    }
108831c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
108931c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell    private void postShowOverflowMenu() {
109031c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        removeCallbacks(mShowOverflowMenuRunnable);
109131c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        post(mShowOverflowMenuRunnable);
109231c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell    }
109331c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
109431c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell    @Override
109531c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell    protected void onDetachedFromWindow() {
109631c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        super.onDetachedFromWindow();
109731c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        removeCallbacks(mShowOverflowMenuRunnable);
1098e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1099e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
110061d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell    @Override
110161d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell    public boolean onTouchEvent(MotionEvent ev) {
110261d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        // Toolbars always eat touch events, but should still respect the touch event dispatch
110361d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        // contract. If the normal View implementation doesn't want the events, we'll just silently
110461d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        // eat the rest of the gesture without reporting the events to the default implementation
110561d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        // since that's what it expects.
110661d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell
110761d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        final int action = ev.getActionMasked();
110861d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        if (action == MotionEvent.ACTION_DOWN) {
110961d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell            mEatingTouch = false;
111061d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        }
111161d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell
111261d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        if (!mEatingTouch) {
111361d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell            final boolean handled = super.onTouchEvent(ev);
111461d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell            if (action == MotionEvent.ACTION_DOWN && !handled) {
111561d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell                mEatingTouch = true;
111661d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell            }
111761d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        }
111861d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell
111961d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
112061d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell            mEatingTouch = false;
112161d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        }
112261d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell
112361d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell        return true;
112461d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell    }
112561d15b98561ab500ccaec5d21d98c8c0ea3ae47fAdam Powell
1126eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell    /**
1127eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell     * @hide
1128eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell     */
1129eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell    @Override
1130eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell    protected void onSetLayoutParams(View child, ViewGroup.LayoutParams lp) {
1131eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell        /*
1132eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell         * Apps may set ActionBar.LayoutParams on their action bar custom views when
1133eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell         * a Toolbar is actually acting in the role of the action bar. Perform a quick
1134eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell         * switch with Toolbar.LayoutParams whenever this happens. This does leave open
1135eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell         * one potential gotcha: if an app retains the ActionBar.LayoutParams reference
1136eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell         * and attempts to keep making changes to it before layout those changes won't
1137eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell         * be reflected in the final results.
1138eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell         */
1139eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell        if (!checkLayoutParams(lp)) {
1140eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell            child.setLayoutParams(generateLayoutParams(lp));
1141eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell        }
1142eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell    }
1143eb97f473fc075c91760c2b657a7014681cd6f3ceAdam Powell
1144e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private void measureChildConstrained(View child, int parentWidthSpec, int widthUsed,
1145e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            int parentHeightSpec, int heightUsed, int heightConstraint) {
1146e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
1147e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1148e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        int childWidthSpec = getChildMeasureSpec(parentWidthSpec,
1149e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
1150e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                        + widthUsed, lp.width);
1151e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        int childHeightSpec = getChildMeasureSpec(parentHeightSpec,
1152e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
1153e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                        + heightUsed, lp.height);
1154e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1155e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        final int childHeightMode = MeasureSpec.getMode(childHeightSpec);
1156e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (childHeightMode != MeasureSpec.EXACTLY && heightConstraint >= 0) {
1157e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final int size = childHeightMode != MeasureSpec.UNSPECIFIED ?
1158e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    Math.min(MeasureSpec.getSize(childHeightSpec), heightConstraint) :
1159e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    heightConstraint;
1160e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            childHeightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
1161e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1162e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        child.measure(childWidthSpec, childHeightSpec);
1163e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
1164e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
11657a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell    /**
11667a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell     * Returns the width + uncollapsed margins
11677a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell     */
11687a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell    private int measureChildCollapseMargins(View child,
11697a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            int parentWidthMeasureSpec, int widthUsed,
11707a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            int parentHeightMeasureSpec, int heightUsed, int[] collapsingMargins) {
11717a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
11727a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell
11737a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int leftDiff = lp.leftMargin - collapsingMargins[0];
11747a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int rightDiff = lp.rightMargin - collapsingMargins[1];
11757a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int leftMargin = Math.max(0, leftDiff);
11767a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int rightMargin = Math.max(0, rightDiff);
11777a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int hMargins = leftMargin + rightMargin;
11787a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        collapsingMargins[0] = Math.max(0, -leftDiff);
11797a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        collapsingMargins[1] = Math.max(0, -rightDiff);
11807a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell
11817a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
11827a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                mPaddingLeft + mPaddingRight + hMargins + widthUsed, lp.width);
11837a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
11847a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
11857a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                        + heightUsed, lp.height);
11867a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell
11877a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
11887a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        return child.getMeasuredWidth() + hMargins;
11897a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell    }
11907a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell
1191360c1d89227570510de7bb11195c986300488464Adam Powell    /**
1192360c1d89227570510de7bb11195c986300488464Adam Powell     * Returns true if the Toolbar is collapsible and has no child views with a measured size > 0.
1193360c1d89227570510de7bb11195c986300488464Adam Powell     */
1194360c1d89227570510de7bb11195c986300488464Adam Powell    private boolean shouldCollapse() {
1195360c1d89227570510de7bb11195c986300488464Adam Powell        if (!mCollapsible) return false;
1196360c1d89227570510de7bb11195c986300488464Adam Powell
1197360c1d89227570510de7bb11195c986300488464Adam Powell        final int childCount = getChildCount();
1198360c1d89227570510de7bb11195c986300488464Adam Powell        for (int i = 0; i < childCount; i++) {
1199360c1d89227570510de7bb11195c986300488464Adam Powell            final View child = getChildAt(i);
1200360c1d89227570510de7bb11195c986300488464Adam Powell            if (shouldLayout(child) && child.getMeasuredWidth() > 0 &&
1201360c1d89227570510de7bb11195c986300488464Adam Powell                    child.getMeasuredHeight() > 0) {
1202360c1d89227570510de7bb11195c986300488464Adam Powell                return false;
1203360c1d89227570510de7bb11195c986300488464Adam Powell            }
1204360c1d89227570510de7bb11195c986300488464Adam Powell        }
1205360c1d89227570510de7bb11195c986300488464Adam Powell        return true;
1206360c1d89227570510de7bb11195c986300488464Adam Powell    }
1207360c1d89227570510de7bb11195c986300488464Adam Powell
1208e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    @Override
1209e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
1210e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int width = 0;
1211e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int height = 0;
1212e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int childState = 0;
1213e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
12147a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int[] collapsingMargins = mTempMargins;
12157a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int marginStartIndex;
12167a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int marginEndIndex;
12177a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        if (isLayoutRtl()) {
12187a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            marginStartIndex = 1;
12197a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            marginEndIndex = 0;
12207a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        } else {
12217a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            marginStartIndex = 0;
12227a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            marginEndIndex = 1;
12237a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        }
12247a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell
1225e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        // System views measure first.
1226e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
122776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        int navWidth = 0;
1228e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (shouldLayout(mNavButtonView)) {
1229e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            measureChildConstrained(mNavButtonView, widthMeasureSpec, width, heightMeasureSpec, 0,
1230e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    mMaxButtonHeight);
123176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell            navWidth = mNavButtonView.getMeasuredWidth() + getHorizontalMargins(mNavButtonView);
1232e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            height = Math.max(height, mNavButtonView.getMeasuredHeight() +
1233e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    getVerticalMargins(mNavButtonView));
1234e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            childState = combineMeasuredStates(childState, mNavButtonView.getMeasuredState());
1235e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1236e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1237e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (shouldLayout(mCollapseButtonView)) {
1238e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            measureChildConstrained(mCollapseButtonView, widthMeasureSpec, width,
1239e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    heightMeasureSpec, 0, mMaxButtonHeight);
1240e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            navWidth = mCollapseButtonView.getMeasuredWidth() +
1241e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    getHorizontalMargins(mCollapseButtonView);
1242e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            height = Math.max(height, mCollapseButtonView.getMeasuredHeight() +
1243e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    getVerticalMargins(mCollapseButtonView));
1244e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            childState = combineMeasuredStates(childState, mCollapseButtonView.getMeasuredState());
1245e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1246e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
12477a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int contentInsetStart = getContentInsetStart();
12487a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        width += Math.max(contentInsetStart, navWidth);
12497a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        collapsingMargins[marginStartIndex] = Math.max(0, contentInsetStart - navWidth);
125076d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
125176d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        int menuWidth = 0;
1252e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (shouldLayout(mMenuView)) {
1253e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            measureChildConstrained(mMenuView, widthMeasureSpec, width, heightMeasureSpec, 0,
1254e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    mMaxButtonHeight);
125576d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell            menuWidth = mMenuView.getMeasuredWidth() + getHorizontalMargins(mMenuView);
1256e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            height = Math.max(height, mMenuView.getMeasuredHeight() +
1257e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    getVerticalMargins(mMenuView));
1258e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            childState = combineMeasuredStates(childState, mMenuView.getMeasuredState());
1259e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1260e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
12617a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int contentInsetEnd = getContentInsetEnd();
12627a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        width += Math.max(contentInsetEnd, menuWidth);
12637a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        collapsingMargins[marginEndIndex] = Math.max(0, contentInsetEnd - menuWidth);
126476d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
1265e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (shouldLayout(mExpandedActionView)) {
12667a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            width += measureChildCollapseMargins(mExpandedActionView, widthMeasureSpec, width,
12677a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    heightMeasureSpec, 0, collapsingMargins);
1268e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            height = Math.max(height, mExpandedActionView.getMeasuredHeight() +
1269e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    getVerticalMargins(mExpandedActionView));
1270e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            childState = combineMeasuredStates(childState, mExpandedActionView.getMeasuredState());
1271e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1272e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1273e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (shouldLayout(mLogoView)) {
12747a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            width += measureChildCollapseMargins(mLogoView, widthMeasureSpec, width,
12757a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    heightMeasureSpec, 0, collapsingMargins);
1276e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            height = Math.max(height, mLogoView.getMeasuredHeight() +
1277e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    getVerticalMargins(mLogoView));
1278e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            childState = combineMeasuredStates(childState, mLogoView.getMeasuredState());
1279e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1280e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1281b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell        final int childCount = getChildCount();
1282b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell        for (int i = 0; i < childCount; i++) {
1283b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell            final View child = getChildAt(i);
1284b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
1285b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell            if (lp.mViewType != LayoutParams.CUSTOM || !shouldLayout(child)) {
1286b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell                // We already got all system views above. Skip them and GONE views.
1287b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell                continue;
1288b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell            }
1289b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell
1290b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell            width += measureChildCollapseMargins(child, widthMeasureSpec, width,
1291b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell                    heightMeasureSpec, 0, collapsingMargins);
1292b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell            height = Math.max(height, child.getMeasuredHeight() + getVerticalMargins(child));
1293b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell            childState = combineMeasuredStates(childState, child.getMeasuredState());
1294b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell        }
1295b606a3a312fe6d69d97c66d76803eb2412d8329aAdam Powell
1296e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int titleWidth = 0;
1297e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int titleHeight = 0;
1298e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int titleVertMargins = mTitleMarginTop + mTitleMarginBottom;
1299e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int titleHorizMargins = mTitleMarginStart + mTitleMarginEnd;
1300e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (shouldLayout(mTitleTextView)) {
13017a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            titleWidth = measureChildCollapseMargins(mTitleTextView, widthMeasureSpec,
13027a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    width + titleHorizMargins, heightMeasureSpec, titleVertMargins,
13037a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    collapsingMargins);
1304e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            titleWidth = mTitleTextView.getMeasuredWidth() + getHorizontalMargins(mTitleTextView);
1305e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            titleHeight = mTitleTextView.getMeasuredHeight() + getVerticalMargins(mTitleTextView);
1306e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            childState = combineMeasuredStates(childState, mTitleTextView.getMeasuredState());
1307e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1308e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (shouldLayout(mSubtitleTextView)) {
13097a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            titleWidth = Math.max(titleWidth, measureChildCollapseMargins(mSubtitleTextView,
13107a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    widthMeasureSpec, width + titleHorizMargins,
13117a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    heightMeasureSpec, titleHeight + titleVertMargins,
13127a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    collapsingMargins));
1313e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            titleHeight += mSubtitleTextView.getMeasuredHeight() +
1314e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    getVerticalMargins(mSubtitleTextView);
1315e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            childState = combineMeasuredStates(childState, mSubtitleTextView.getMeasuredState());
1316e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1317e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1318e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        width += titleWidth;
1319e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        height = Math.max(height, titleHeight);
1320e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1321e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        // Measurement already took padding into account for available space for the children,
1322e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        // add it in for the final size.
1323e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        width += getPaddingLeft() + getPaddingRight();
1324e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        height += getPaddingTop() + getPaddingBottom();
1325e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1326e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int measuredWidth = resolveSizeAndState(
1327e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                Math.max(width, getSuggestedMinimumWidth()),
1328e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                widthMeasureSpec, childState & MEASURED_STATE_MASK);
1329e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int measuredHeight = resolveSizeAndState(
1330e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                Math.max(height, getSuggestedMinimumHeight()),
1331e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT);
1332360c1d89227570510de7bb11195c986300488464Adam Powell
1333360c1d89227570510de7bb11195c986300488464Adam Powell        setMeasuredDimension(measuredWidth, shouldCollapse() ? 0 : measuredHeight);
1334e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1335e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1336e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    @Override
1337e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    protected void onLayout(boolean changed, int l, int t, int r, int b) {
1338e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
1339e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int width = getWidth();
1340e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int height = getHeight();
1341e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int paddingLeft = getPaddingLeft();
1342e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int paddingRight = getPaddingRight();
1343e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int paddingTop = getPaddingTop();
1344e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int paddingBottom = getPaddingBottom();
1345e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int left = paddingLeft;
1346e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int right = width - paddingRight;
1347e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
13487a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int[] collapsingMargins = mTempMargins;
13497a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        collapsingMargins[0] = collapsingMargins[1] = 0;
13507a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell
1351e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        // Align views within the minimum toolbar height, if set.
1352e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        final int alignmentHeight = getMinimumHeight();
1353e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette
1354e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (shouldLayout(mNavButtonView)) {
1355e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (isRtl) {
1356e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                right = layoutChildRight(mNavButtonView, right, collapsingMargins,
1357e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1358e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            } else {
1359e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                left = layoutChildLeft(mNavButtonView, left, collapsingMargins,
1360e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1361e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
1362e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1363e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1364e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (shouldLayout(mCollapseButtonView)) {
1365e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (isRtl) {
1366e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                right = layoutChildRight(mCollapseButtonView, right, collapsingMargins,
1367e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1368e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            } else {
1369e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins,
1370e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1371e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
1372e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1373e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1374e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (shouldLayout(mMenuView)) {
1375e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (isRtl) {
1376e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                left = layoutChildLeft(mMenuView, left, collapsingMargins,
1377e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1378e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            } else {
1379e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                right = layoutChildRight(mMenuView, right, collapsingMargins,
1380e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1381e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
1382e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1383e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
13847a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        collapsingMargins[0] = Math.max(0, getContentInsetLeft() - left);
13857a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        collapsingMargins[1] = Math.max(0, getContentInsetRight() - (width - paddingRight - right));
138676d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        left = Math.max(left, getContentInsetLeft());
138776d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell        right = Math.min(right, width - paddingRight - getContentInsetRight());
138876d8f968059d27ef8500cabf7690c18552c22d5aAdam Powell
1389e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (shouldLayout(mExpandedActionView)) {
1390e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (isRtl) {
1391e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                right = layoutChildRight(mExpandedActionView, right, collapsingMargins,
1392e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1393e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            } else {
1394e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                left = layoutChildLeft(mExpandedActionView, left, collapsingMargins,
1395e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1396e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
1397e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1398e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1399e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (shouldLayout(mLogoView)) {
1400e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (isRtl) {
1401e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                right = layoutChildRight(mLogoView, right, collapsingMargins,
1402e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1403e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            } else {
1404e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                left = layoutChildLeft(mLogoView, left, collapsingMargins,
1405e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        alignmentHeight);
1406e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
1407e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1408e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1409e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final boolean layoutTitle = shouldLayout(mTitleTextView);
1410e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final boolean layoutSubtitle = shouldLayout(mSubtitleTextView);
1411e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int titleHeight = 0;
1412e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (layoutTitle) {
1413e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
1414e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            titleHeight += lp.topMargin + mTitleTextView.getMeasuredHeight() + lp.bottomMargin;
1415e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1416e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (layoutSubtitle) {
1417e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams();
1418b3e411458cd7b96bb308e2de3086efc4da10d64dAdam Powell            titleHeight += lp.topMargin + mSubtitleTextView.getMeasuredHeight() + lp.bottomMargin;
1419e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1420e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1421e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (layoutTitle || layoutSubtitle) {
1422e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            int titleTop;
1423e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final View topChild = layoutTitle ? mTitleTextView : mSubtitleTextView;
1424e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final View bottomChild = layoutSubtitle ? mSubtitleTextView : mTitleTextView;
1425e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final LayoutParams toplp = (LayoutParams) topChild.getLayoutParams();
1426e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final LayoutParams bottomlp = (LayoutParams) bottomChild.getLayoutParams();
14274c9765a654f7db15091d373f989908da54bfd155Adam Powell            final boolean titleHasWidth = layoutTitle && mTitleTextView.getMeasuredWidth() > 0
14284c9765a654f7db15091d373f989908da54bfd155Adam Powell                    || layoutSubtitle && mSubtitleTextView.getMeasuredWidth() > 0;
1429e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1430e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) {
1431e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                case Gravity.TOP:
1432e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    titleTop = getPaddingTop() + toplp.topMargin + mTitleMarginTop;
1433e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    break;
1434e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                default:
1435e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                case Gravity.CENTER_VERTICAL:
1436e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int space = height - paddingTop - paddingBottom;
1437e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    int spaceAbove = (space - titleHeight) / 2;
1438e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    if (spaceAbove < toplp.topMargin + mTitleMarginTop) {
1439e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                        spaceAbove = toplp.topMargin + mTitleMarginTop;
1440e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    } else {
1441e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                        final int spaceBelow = height - paddingBottom - titleHeight -
1442e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                                spaceAbove - paddingTop;
1443e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                        if (spaceBelow < toplp.bottomMargin + mTitleMarginBottom) {
1444e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                            spaceAbove = Math.max(0, spaceAbove -
1445e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                                    (bottomlp.bottomMargin + mTitleMarginBottom - spaceBelow));
1446e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                        }
1447e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    }
1448e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    titleTop = paddingTop + spaceAbove;
1449e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    break;
1450e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                case Gravity.BOTTOM:
1451e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    titleTop = height - paddingBottom - bottomlp.bottomMargin - mTitleMarginBottom -
1452e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                            titleHeight;
1453e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    break;
1454e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
1455e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            if (isRtl) {
14564c9765a654f7db15091d373f989908da54bfd155Adam Powell                final int rd = (titleHasWidth ? mTitleMarginStart : 0) - collapsingMargins[1];
14577a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                right -= Math.max(0, rd);
14587a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                collapsingMargins[1] = Math.max(0, -rd);
1459e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                int titleRight = right;
1460e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                int subtitleRight = right;
14617a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell
1462e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                if (layoutTitle) {
1463e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
1464e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int titleLeft = titleRight - mTitleTextView.getMeasuredWidth();
1465e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
1466e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
14677a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    titleRight = titleLeft - mTitleMarginEnd;
1468e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    titleTop = titleBottom + lp.bottomMargin;
1469e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                }
1470e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                if (layoutSubtitle) {
1471e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams();
1472e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    titleTop += lp.topMargin;
1473e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int subtitleLeft = subtitleRight - mSubtitleTextView.getMeasuredWidth();
1474e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight();
1475e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom);
14767a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    subtitleRight = subtitleRight - mTitleMarginEnd;
1477e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    titleTop = subtitleBottom + lp.bottomMargin;
1478e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                }
14794c9765a654f7db15091d373f989908da54bfd155Adam Powell                if (titleHasWidth) {
14804c9765a654f7db15091d373f989908da54bfd155Adam Powell                    right = Math.min(titleRight, subtitleRight);
14814c9765a654f7db15091d373f989908da54bfd155Adam Powell                }
1482e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            } else {
14834c9765a654f7db15091d373f989908da54bfd155Adam Powell                final int ld = (titleHasWidth ? mTitleMarginStart : 0) - collapsingMargins[0];
14847a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                left += Math.max(0, ld);
14857a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                collapsingMargins[0] = Math.max(0, -ld);
1486e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                int titleLeft = left;
1487e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                int subtitleLeft = left;
14887a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell
1489e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                if (layoutTitle) {
1490e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
1491e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int titleRight = titleLeft + mTitleTextView.getMeasuredWidth();
1492e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
1493e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
14947a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    titleLeft = titleRight + mTitleMarginEnd;
1495e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    titleTop = titleBottom + lp.bottomMargin;
1496e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                }
1497e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                if (layoutSubtitle) {
1498e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams();
1499e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    titleTop += lp.topMargin;
1500e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int subtitleRight = subtitleLeft + mSubtitleTextView.getMeasuredWidth();
1501e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight();
1502e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom);
15037a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell                    subtitleLeft = subtitleRight + mTitleMarginEnd;
1504e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    titleTop = subtitleBottom + lp.bottomMargin;
1505e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                }
15064c9765a654f7db15091d373f989908da54bfd155Adam Powell                if (titleHasWidth) {
15074c9765a654f7db15091d373f989908da54bfd155Adam Powell                    left = Math.max(titleLeft, subtitleLeft);
15084c9765a654f7db15091d373f989908da54bfd155Adam Powell                }
1509e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
1510e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1511e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1512e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        // Get all remaining children sorted for layout. This is all prepared
1513e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        // such that absolute layout direction can be used below.
1514e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1515e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        addCustomViewsWithGravity(mTempViews, Gravity.LEFT);
1516e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int leftViewsCount = mTempViews.size();
1517e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        for (int i = 0; i < leftViewsCount; i++) {
1518e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette            left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins,
1519e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                    alignmentHeight);
1520e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1521e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1522e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        addCustomViewsWithGravity(mTempViews, Gravity.RIGHT);
1523e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int rightViewsCount = mTempViews.size();
1524e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        for (int i = 0; i < rightViewsCount; i++) {
1525e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette            right = layoutChildRight(mTempViews.get(i), right, collapsingMargins,
1526e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                    alignmentHeight);
1527e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1528e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1529e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        // Centered views try to center with respect to the whole bar, but views pinned
1530e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        // to the left or right can push the mass of centered views to one side or the other.
1531e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        addCustomViewsWithGravity(mTempViews, Gravity.CENTER_HORIZONTAL);
15327a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int centerViewsWidth = getViewListMeasuredWidth(mTempViews, collapsingMargins);
1533e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int parentCenter = paddingLeft + (width - paddingLeft - paddingRight) / 2;
1534e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int halfCenterViewsWidth = centerViewsWidth / 2;
1535e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int centerLeft = parentCenter - halfCenterViewsWidth;
1536e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int centerRight = centerLeft + centerViewsWidth;
1537e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (centerLeft < left) {
1538e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            centerLeft = left;
1539e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        } else if (centerRight > right) {
1540e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            centerLeft -= centerRight - right;
1541e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1542e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1543e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int centerViewsCount = mTempViews.size();
1544e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        for (int i = 0; i < centerViewsCount; i++) {
1545e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette            centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins,
1546e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                    alignmentHeight);
1547e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1548e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette
1549e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        mTempViews.clear();
1550e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1551e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
15527a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell    private int getViewListMeasuredWidth(List<View> views, int[] collapsingMargins) {
15537a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        int collapseLeft = collapsingMargins[0];
15547a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        int collapseRight = collapsingMargins[1];
1555e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int width = 0;
1556e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int count = views.size();
1557e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        for (int i = 0; i < count; i++) {
1558e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            final View v = views.get(i);
1559e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            final LayoutParams lp = (LayoutParams) v.getLayoutParams();
15607a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            final int l = lp.leftMargin - collapseLeft;
15617a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            final int r = lp.rightMargin - collapseRight;
15627a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            final int leftMargin = Math.max(0, l);
15637a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            final int rightMargin = Math.max(0, r);
15647a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            collapseLeft = Math.max(0, -l);
15657a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            collapseRight = Math.max(0, -r);
15667a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell            width += leftMargin + v.getMeasuredWidth() + rightMargin;
1567e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1568e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return width;
1569e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1570e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1571e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette    private int layoutChildLeft(View child, int left, int[] collapsingMargins,
1572e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette            int alignmentHeight) {
1573e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
15747a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int l = lp.leftMargin - collapsingMargins[0];
15757a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        left += Math.max(0, l);
15767a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        collapsingMargins[0] = Math.max(0, -l);
1577e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        final int top = getChildTop(child, alignmentHeight);
15787a8a284d46c740e8b2cd1ccd088c0ba41e020642Adam Powell        final int childWidth = child.getMeasuredWidth();
15797a8a284d46c740e8b2cd1ccd088c0ba41e020642Adam Powell        child.layout(left, top, left + childWidth, top + child.getMeasuredHeight());
15807a8a284d46c740e8b2cd1ccd088c0ba41e020642Adam Powell        left += childWidth + lp.rightMargin;
1581e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return left;
1582e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1583e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1584e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette    private int layoutChildRight(View child, int right, int[] collapsingMargins,
1585e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette            int alignmentHeight) {
1586e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
15877a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        final int r = lp.rightMargin - collapsingMargins[1];
15887a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        right -= Math.max(0, r);
15897a32401c2a62f778da7056cc9aa65bd1489aa153Adam Powell        collapsingMargins[1] = Math.max(0, -r);
1590e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        final int top = getChildTop(child, alignmentHeight);
15917a8a284d46c740e8b2cd1ccd088c0ba41e020642Adam Powell        final int childWidth = child.getMeasuredWidth();
15927a8a284d46c740e8b2cd1ccd088c0ba41e020642Adam Powell        child.layout(right - childWidth, top, right, top + child.getMeasuredHeight());
15937a8a284d46c740e8b2cd1ccd088c0ba41e020642Adam Powell        right -= childWidth + lp.leftMargin;
1594e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return right;
1595e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1596e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1597e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette    private int getChildTop(View child, int alignmentHeight) {
1598e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
1599e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        final int childHeight = child.getMeasuredHeight();
1600e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette        final int alignmentOffset = alignmentHeight > 0 ? (childHeight - alignmentHeight) / 2 : 0;
1601e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        switch (getChildVerticalGravity(lp.gravity)) {
1602e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            case Gravity.TOP:
1603e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                return getPaddingTop() - alignmentOffset;
1604e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1605e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            case Gravity.BOTTOM:
1606e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                return getHeight() - getPaddingBottom() - childHeight
1607e3cb7baeb9563cd78fecbd84f9ab43be62d25013Alan Viverette                        - lp.bottomMargin - alignmentOffset;
1608e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1609e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            default:
1610e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            case Gravity.CENTER_VERTICAL:
1611e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final int paddingTop = getPaddingTop();
1612e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final int paddingBottom = getPaddingBottom();
1613e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final int height = getHeight();
1614e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final int space = height - paddingTop - paddingBottom;
1615e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                int spaceAbove = (space - childHeight) / 2;
1616e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                if (spaceAbove < lp.topMargin) {
1617e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    spaceAbove = lp.topMargin;
1618e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                } else {
1619e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    final int spaceBelow = height - paddingBottom - childHeight -
1620e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                            spaceAbove - paddingTop;
1621e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    if (spaceBelow < lp.bottomMargin) {
1622e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                        spaceAbove = Math.max(0, spaceAbove - (lp.bottomMargin - spaceBelow));
1623e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    }
1624e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                }
1625e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                return paddingTop + spaceAbove;
1626e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1627e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1628e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1629e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int getChildVerticalGravity(int gravity) {
1630e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int vgrav = gravity & Gravity.VERTICAL_GRAVITY_MASK;
1631e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        switch (vgrav) {
1632e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            case Gravity.TOP:
1633e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            case Gravity.BOTTOM:
1634e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            case Gravity.CENTER_VERTICAL:
1635e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                return vgrav;
1636e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            default:
1637e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                return mGravity & Gravity.VERTICAL_GRAVITY_MASK;
1638e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1639e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1640e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1641e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
1642e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Prepare a list of non-SYSTEM child views. If the layout direction is RTL
1643e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * this will be in reverse child order.
1644e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
1645e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param views List to populate. It will be cleared before use.
1646e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @param gravity Horizontal gravity to match against
1647e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
1648e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private void addCustomViewsWithGravity(List<View> views, int gravity) {
1649e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
1650e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int childCount = getChildCount();
1651e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int absGrav = Gravity.getAbsoluteGravity(gravity, getLayoutDirection());
1652e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1653e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        views.clear();
1654e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1655e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (isRtl) {
1656e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            for (int i = childCount - 1; i >= 0; i--) {
1657e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final View child = getChildAt(i);
1658e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
1659e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
1660e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                        getChildHorizontalGravity(lp.gravity) == absGrav) {
1661e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    views.add(child);
1662e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                }
1663e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
1664e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        } else {
1665e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            for (int i = 0; i < childCount; i++) {
1666e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final View child = getChildAt(i);
1667e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
1668e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
1669e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                        getChildHorizontalGravity(lp.gravity) == absGrav) {
1670e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                    views.add(child);
1671e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                }
1672e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
1673e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1674e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1675e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1676e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int getChildHorizontalGravity(int gravity) {
1677e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int ld = getLayoutDirection();
1678e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int absGrav = Gravity.getAbsoluteGravity(gravity, ld);
1679e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final int hGrav = absGrav & Gravity.HORIZONTAL_GRAVITY_MASK;
1680e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        switch (hGrav) {
1681e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            case Gravity.LEFT:
1682e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            case Gravity.RIGHT:
1683e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            case Gravity.CENTER_HORIZONTAL:
1684e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                return hGrav;
1685e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            default:
1686e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                return ld == LAYOUT_DIRECTION_RTL ? Gravity.RIGHT : Gravity.LEFT;
1687e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1688e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1689e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1690e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private boolean shouldLayout(View view) {
1691e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return view != null && view.getParent() == this && view.getVisibility() != GONE;
1692e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1693e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1694e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int getHorizontalMargins(View v) {
1695e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
1696e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return mlp.getMarginStart() + mlp.getMarginEnd();
1697e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1698e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1699e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private int getVerticalMargins(View v) {
1700e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        final MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
1701e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return mlp.topMargin + mlp.bottomMargin;
1702e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1703e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1704e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    @Override
1705e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public LayoutParams generateLayoutParams(AttributeSet attrs) {
1706e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return new LayoutParams(getContext(), attrs);
1707e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1708e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1709e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    @Override
1710e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
1711e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        if (p instanceof LayoutParams) {
1712e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            return new LayoutParams((LayoutParams) p);
1713e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        } else if (p instanceof ActionBar.LayoutParams) {
1714e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return new LayoutParams((ActionBar.LayoutParams) p);
1715e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        } else if (p instanceof MarginLayoutParams) {
1716e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            return new LayoutParams((MarginLayoutParams) p);
1717e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        } else {
1718e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            return new LayoutParams(p);
1719e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1720e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1721e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1722e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    @Override
1723e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    protected LayoutParams generateDefaultLayoutParams() {
1724e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
1725e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1726e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1727e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    @Override
1728e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
1729e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return super.checkLayoutParams(p) && p instanceof LayoutParams;
1730e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1731e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1732e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    private static boolean isCustomView(View child) {
1733e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        return ((LayoutParams) child.getLayoutParams()).mViewType == LayoutParams.CUSTOM;
1734e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1735e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1736e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    /** @hide */
1737e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public DecorToolbar getWrapper() {
1738e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (mWrapper == null) {
17392aa09a94dd540650d3ebad7363e4fb3aab2ebc95Adam Powell            mWrapper = new ToolbarWidgetWrapper(this, true);
1740e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1741e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mWrapper;
1742e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
1743e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1744e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private void setChildVisibilityForExpandedActionView(boolean expand) {
1745e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        final int childCount = getChildCount();
1746e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        for (int i = 0; i < childCount; i++) {
1747e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final View child = getChildAt(i);
1748e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
1749e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
1750e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                child.setVisibility(expand ? GONE : VISIBLE);
1751e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
1752e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1753e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
1754e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
175531c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell    private void updateChildVisibilityForExpandedActionView(View child) {
175631c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
175731c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
175831c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            child.setVisibility(mExpandedActionView != null ? GONE : VISIBLE);
175931c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        }
176031c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell    }
176131c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
1762e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
1763360c1d89227570510de7bb11195c986300488464Adam Powell     * Force the toolbar to collapse to zero-height during measurement if
1764360c1d89227570510de7bb11195c986300488464Adam Powell     * it could be considered "empty" (no visible elements with nonzero measured size)
1765360c1d89227570510de7bb11195c986300488464Adam Powell     * @hide
1766360c1d89227570510de7bb11195c986300488464Adam Powell     */
1767360c1d89227570510de7bb11195c986300488464Adam Powell    public void setCollapsible(boolean collapsible) {
1768360c1d89227570510de7bb11195c986300488464Adam Powell        mCollapsible = collapsible;
1769360c1d89227570510de7bb11195c986300488464Adam Powell        requestLayout();
1770360c1d89227570510de7bb11195c986300488464Adam Powell    }
1771360c1d89227570510de7bb11195c986300488464Adam Powell
1772360c1d89227570510de7bb11195c986300488464Adam Powell    /**
177304c0d4607897157f01c908475fa0c6d7301cf7e5Adam Powell     * Must be called before the menu is accessed
177404c0d4607897157f01c908475fa0c6d7301cf7e5Adam Powell     * @hide
177504c0d4607897157f01c908475fa0c6d7301cf7e5Adam Powell     */
1776c46125042493e66f7dfdccec24e3b0739600b194Adam Powell    public void setMenuCallbacks(MenuPresenter.Callback pcb, MenuBuilder.Callback mcb) {
1777c46125042493e66f7dfdccec24e3b0739600b194Adam Powell        mActionMenuPresenterCallback = pcb;
1778c46125042493e66f7dfdccec24e3b0739600b194Adam Powell        mMenuBuilderCallback = mcb;
177904c0d4607897157f01c908475fa0c6d7301cf7e5Adam Powell    }
178004c0d4607897157f01c908475fa0c6d7301cf7e5Adam Powell
178104c0d4607897157f01c908475fa0c6d7301cf7e5Adam Powell    /**
17820bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta     * Accessor to enable LayoutLib to get ActionMenuPresenter directly.
17830bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta     */
17840bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta    ActionMenuPresenter getOuterActionMenuPresenter() {
17850bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta        return mOuterActionMenuPresenter;
17860bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta    }
17870bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta
17880bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta    Context getPopupContext() {
17890bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta        return mPopupContext;
17900bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta    }
17910bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta
17920bffc736e1f260724764d31f7499cbc09471a535Deepanshu Gupta    /**
1793e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Interface responsible for receiving menu item click events if the items themselves
1794e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * do not have individual item click listeners.
1795e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
1796e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    public interface OnMenuItemClickListener {
1797e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        /**
1798e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell         * This method will be invoked when a menu item is clicked if the item itself did
1799e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell         * not already handle the event.
1800e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell         *
1801e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell         * @param item {@link MenuItem} that was clicked
1802e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell         * @return <code>true</code> if the event was handled, <code>false</code> otherwise.
1803e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell         */
1804e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public boolean onMenuItemClick(MenuItem item);
1805e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1806e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1807e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    /**
1808e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * Layout information for child views of Toolbars.
1809e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     *
1810d76008352eeb246af76ba4a81eaeb4901ca4ef7fAdam Powell     * <p>Toolbar.LayoutParams extends ActionBar.LayoutParams for compatibility with existing
1811d76008352eeb246af76ba4a81eaeb4901ca4ef7fAdam Powell     * ActionBar API. See {@link android.app.Activity#setActionBar(Toolbar) Activity.setActionBar}
1812d76008352eeb246af76ba4a81eaeb4901ca4ef7fAdam Powell     * for more info on how to use a Toolbar as your Activity's ActionBar.</p>
1813d76008352eeb246af76ba4a81eaeb4901ca4ef7fAdam Powell     *
1814e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     * @attr ref android.R.styleable#Toolbar_LayoutParams_layout_gravity
1815e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell     */
1816e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    public static class LayoutParams extends ActionBar.LayoutParams {
1817e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        static final int CUSTOM = 0;
1818e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        static final int SYSTEM = 1;
1819e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        static final int EXPANDED = 2;
1820e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1821e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        int mViewType = CUSTOM;
1822e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1823e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public LayoutParams(@NonNull Context c, AttributeSet attrs) {
1824e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            super(c, attrs);
1825e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1826e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1827e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public LayoutParams(int width, int height) {
1828e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            super(width, height);
1829e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            this.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
1830e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1831e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1832e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public LayoutParams(int width, int height, int gravity) {
1833e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            super(width, height);
1834e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            this.gravity = gravity;
1835e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1836e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1837e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public LayoutParams(int gravity) {
1838e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            this(WRAP_CONTENT, MATCH_PARENT, gravity);
1839e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1840e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1841e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public LayoutParams(LayoutParams source) {
1842e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            super(source);
1843e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1844e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mViewType = source.mViewType;
1845e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1846e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1847e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public LayoutParams(ActionBar.LayoutParams source) {
1848e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            super(source);
1849e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1850e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1851e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public LayoutParams(MarginLayoutParams source) {
1852e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            super(source);
1853d76008352eeb246af76ba4a81eaeb4901ca4ef7fAdam Powell            // ActionBar.LayoutParams doesn't have a MarginLayoutParams constructor.
1854d76008352eeb246af76ba4a81eaeb4901ca4ef7fAdam Powell            // Fake it here and copy over the relevant data.
1855d76008352eeb246af76ba4a81eaeb4901ca4ef7fAdam Powell            copyMarginsFrom(source);
1856e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1857e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1858e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public LayoutParams(ViewGroup.LayoutParams source) {
1859e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            super(source);
1860e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1861e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1862e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1863e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    static class SavedState extends BaseSavedState {
186431c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        public int expandedMenuItemId;
186531c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell        public boolean isOverflowOpen;
186631c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell
1867e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public SavedState(Parcel source) {
1868e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            super(source);
186931c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            expandedMenuItemId = source.readInt();
187031c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            isOverflowOpen = source.readInt() != 0;
1871e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1872e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1873e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public SavedState(Parcelable superState) {
1874e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            super(superState);
1875e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1876e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1877e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        @Override
1878e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public void writeToParcel(Parcel out, int flags) {
1879e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            super.writeToParcel(out, flags);
188031c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            out.writeInt(expandedMenuItemId);
188131c91c81798802f62d55f8bccb6d4071471c1aa4Adam Powell            out.writeInt(isOverflowOpen ? 1 : 0);
1882e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        }
1883e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1884e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
1885e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1886e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            @Override
1887e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            public SavedState createFromParcel(Parcel source) {
1888e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                return new SavedState(source);
1889e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
1890e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell
1891e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            @Override
1892e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            public SavedState[] newArray(int size) {
1893e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell                return new SavedState[size];
1894e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell            }
1895e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell        };
1896e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell    }
1897e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1898e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private class ExpandedActionViewMenuPresenter implements MenuPresenter {
1899e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        MenuBuilder mMenu;
1900e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        MenuItemImpl mCurrentExpandedItem;
1901e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1902e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
1903e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public void initForMenu(Context context, MenuBuilder menu) {
1904e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            // Clear the expanded action view when menus change.
1905e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (mMenu != null && mCurrentExpandedItem != null) {
1906e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mMenu.collapseItemActionView(mCurrentExpandedItem);
1907e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
1908e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mMenu = menu;
1909e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1910e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1911e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
1912e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public MenuView getMenuView(ViewGroup root) {
1913e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return null;
1914e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1915e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1916e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
1917e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public void updateMenuView(boolean cleared) {
1918e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            // Make sure the expanded item we have is still there.
1919e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (mCurrentExpandedItem != null) {
1920e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                boolean found = false;
1921e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1922e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                if (mMenu != null) {
1923e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    final int count = mMenu.size();
1924e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    for (int i = 0; i < count; i++) {
1925e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                        final MenuItem item = mMenu.getItem(i);
1926e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                        if (item == mCurrentExpandedItem) {
1927e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                            found = true;
1928e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                            break;
1929e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                        }
1930e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    }
1931e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                }
1932e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1933e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                if (!found) {
1934e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    // The item we had expanded disappeared. Collapse.
1935e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    collapseItemActionView(mMenu, mCurrentExpandedItem);
1936e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                }
1937e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
1938e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1939e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1940e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
1941e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public void setCallback(Callback cb) {
1942e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1943e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1944e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
1945e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
1946e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return false;
1947e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1948e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1949e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
1950e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
1951e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1952e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1953e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
1954e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public boolean flagActionItems() {
1955e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return false;
1956e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1957e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1958e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
1959e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
1960e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            ensureCollapseButtonView();
1961e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (mCollapseButtonView.getParent() != Toolbar.this) {
1962e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                addView(mCollapseButtonView);
1963e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
1964e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mExpandedActionView = item.getActionView();
1965e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mCurrentExpandedItem = item;
1966e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (mExpandedActionView.getParent() != Toolbar.this) {
1967e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                final LayoutParams lp = generateDefaultLayoutParams();
1968e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
1969e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                lp.mViewType = LayoutParams.EXPANDED;
1970e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mExpandedActionView.setLayoutParams(lp);
1971e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                addView(mExpandedActionView);
1972e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
1973e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1974e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            setChildVisibilityForExpandedActionView(true);
1975e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            requestLayout();
1976e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            item.setActionViewExpanded(true);
1977e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1978e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (mExpandedActionView instanceof CollapsibleActionView) {
1979e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
1980e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
1981e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1982e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return true;
1983e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
1984e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1985e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
1986e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
1987e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            // Do this before detaching the actionview from the hierarchy, in case
1988e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            // it needs to dismiss the soft keyboard, etc.
1989e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (mExpandedActionView instanceof CollapsibleActionView) {
1990e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
1991e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            }
1992e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1993e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            removeView(mExpandedActionView);
1994e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            removeView(mCollapseButtonView);
1995e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mExpandedActionView = null;
1996e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
1997e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            setChildVisibilityForExpandedActionView(false);
1998e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mCurrentExpandedItem = null;
1999e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            requestLayout();
2000e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            item.setActionViewExpanded(false);
2001e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
2002e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return true;
2003e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
2004e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
2005e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
2006e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public int getId() {
2007e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return 0;
2008e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
2009e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
2010e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
2011e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public Parcelable onSaveInstanceState() {
2012e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return null;
2013e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
2014e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
2015e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        @Override
2016e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        public void onRestoreInstanceState(Parcelable state) {
2017e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
2018e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
2019e43340c80dc66c45edc793ecd0343774aa34d108Adam Powell}
2020