content: package com.alirezaafkar.toolbar;
  
  import android.content.Context;
  import android.content.res.AssetManager;
  import android.graphics.Typeface;
  import android.graphics.drawable.Drawable;
  import android.os.Build;
  import android.os.Parcel;
  import android.os.Parcelable;
  import android.support.annotation.ColorInt;
  import android.support.annotation.DrawableRes;
  import android.support.annotation.MenuRes;
  import android.support.annotation.NonNull;
  import android.support.annotation.Nullable;
  import android.support.annotation.StringRes;
  import android.support.annotation.StyleRes;
  import android.support.v4.view.GravityCompat;
  import android.support.v4.view.MarginLayoutParamsCompat;
  import android.support.v4.view.MenuItemCompat;
  import android.support.v4.view.MotionEventCompat;
  import android.support.v4.view.ViewCompat;
  import android.support.v7.app.ActionBar;
  import android.support.v7.view.CollapsibleActionView;
  import android.support.v7.view.SupportMenuInflater;
  import android.support.v7.view.menu.ActionMenuItem;
  import android.support.v7.view.menu.MenuBuilder;
  import android.support.v7.view.menu.MenuItemImpl;
  import android.support.v7.view.menu.MenuPresenter;
  import android.support.v7.view.menu.MenuView;
  import android.support.v7.view.menu.SubMenuBuilder;
  import android.support.v7.widget.AppCompatDrawableManager;
  import android.support.v7.widget.DecorToolbar;
  import android.support.v7.widget.TintTypedArray;
  import android.support.v7.widget.Toolbar;
  import android.support.v7.widget.ViewUtils;
  import android.text.Layout;
  import android.text.TextUtils;
  import android.util.AttributeSet;
  import android.view.ContextThemeWrapper;
  import android.view.Gravity;
  import android.view.Menu;
  import android.view.MenuInflater;
  import android.view.MenuItem;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.ImageButton;
  import android.widget.ImageView;
  import android.widget.TextView;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * A standard toolbar for use within application content.
   * <p/>
   * <p>A Toolbar is a generalization of {@link ActionBar action bars} for use
   * within application layouts. While an action bar is traditionally part of an
   * {@link android.app.Activity Activity's} opaque window decor controlled by the framework,
   * a Toolbar may be placed at any arbitrary level of nesting within a view hierarchy.
   * An application may choose to designate a Toolbar as the action bar for an Activity
   * using the {@link android.support.v7.app.AppCompatActivity#setSupportActionBar(RtlToolbar)
   * setSupportActionBar()} method.</p>
   * <p/>
   * <p>Toolbar supports a more focused feature set than ActionBar. From start to end, a toolbar
   * may contain a combination of the following optional elements:
   * <p/>
   * <ul>
   * <li><em>A navigation button.</em> This may be an Up arrow, navigation menu toggle, close,
   * collapse, done or another glyph of the app's choosing. This button should always be used
   * to access other navigational destinations within the container of the Toolbar and
   * its signified content or otherwise leave the current context signified by the Toolbar.
   * The navigation button is vertically aligned within the Toolbar's minimum height,
   * if set.</li>
   * <li><em>A branded logo image.</em> This may extend to the height of the bar and can be
   * arbitrarily wide.</li>
   * <li><em>A title and subtitle.</em> The title should be a signpost for the Toolbar's current
   * position in the navigation hierarchy and the content contained there. The subtitle,
   * if present should indicate any extended information about the current content.
   * If an app uses a logo image it should strongly consider omitting a title and subtitle.</li>
   * <li><em>One or more custom views.</em> The application may add arbitrary child views
   * to the Toolbar. They will appear at this position within the layout. If a child view's
   * {@link LayoutParams} indicates a {@link Gravity} value of
   * {@link Gravity#CENTER_HORIZONTAL CENTER_HORIZONTAL} the view will attempt to center
   * within the available space remaining in the Toolbar after all other elements have been
   * measured.</li>
   * <li><em>An {@link android.support.v7.widget.ActionMenuView action menu}.</em> The menu of actions will pin to the
   * end of the Toolbar offering a few
   * <a href="http://developer.android.com/design/patterns/actionbar.html#ActionButtons">
   * frequent, important or typical</a> actions along with an optional overflow menu for
   * additional actions. Action buttons are vertically aligned within the Toolbar's
   * minimum height, if set.</li>
   * </ul>
   * </p>
   * <p/>
   * <p>In modern Android UIs developers should lean more on a visually distinct color scheme for
   * toolbars than on their application icon. The use of application icon plus title as a standard
   * layout is discouraged on API 21 devices and newer.</p>
   */
  @SuppressWarnings("ALL")
  public class RtlToolbar extends ViewGroup {
      public static final int LOCALE = 0;
      public static final int LTR = 1;
      public static final int RTL = 2;
  
      private ActionMenuView mMenuView;
      private TextView mTitleTextView;
      private TextView mSubtitleTextView;
      private ImageButton mNavButtonView;
      private ImageView mLogoView;
  
      private Drawable mCollapseIcon;
      private CharSequence mCollapseDescription;
      private ImageButton mCollapseButtonView;
      View mExpandedActionView;
  
      /**
       * Context against which to inflate popup menus.
       */
      private Context mPopupContext;
  
      /**
       * Theme resource against which to inflate popup menus.
       */
      private int mPopupTheme;
  
      private int mTitleTextAppearance;
      private int mSubtitleTextAppearance;
  
      private int mButtonGravity;
  
      private int mMaxButtonHeight;
  
      private int mTitleMarginStart;
      private int mTitleMarginEnd;
      private int mTitleMarginTop;
      private int mTitleMarginBottom;
  
      private final RtlSpacingHelper mContentInsets = new RtlSpacingHelper();
  
      private int mGravity = GravityCompat.START | Gravity.CENTER_VERTICAL;
  
      private int mDirection;
  
      private CharSequence mTitleText;
      private CharSequence mSubtitleText;
  
      private String mTitleFont;
  
      private int mTitleTextColor;
      private int mSubtitleTextColor;
  
      private boolean mEatingTouch;
      private boolean mEatingHover;
  
      // Clear me after use.
      private final ArrayList<View> mTempViews = new ArrayList<View>();
  
      // Used to hold views that will be removed while we have an expanded action view.
      private final ArrayList<View> mHiddenViews = new ArrayList<>();
  
      private final int[] mTempMargins = new int[2];
  
      private OnMenuItemClickListener mOnMenuItemClickListener;
  
      private final ActionMenuView.OnMenuItemClickListener mMenuViewItemClickListener =
              new ActionMenuView.OnMenuItemClickListener() {
                  @Override
                  public boolean onMenuItemClick(MenuItem item) {
                      if (mOnMenuItemClickListener != null) {
                          return mOnMenuItemClickListener.onMenuItemClick(item);
                      }
                      return false;
                  }
              };
  
      private ToolbarWidgetWrapper mWrapper;
      private ActionMenuPresenter mOuterActionMenuPresenter;
      private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
      private MenuPresenter.Callback mActionMenuPresenterCallback;
      private MenuBuilder.Callback mMenuBuilderCallback;
  
      private boolean mCollapsible;
  
      private final Runnable mShowOverflowMenuRunnable = new Runnable() {
          @Override
          public void run() {
              showOverflowMenu();
          }
      };
  
      private final AppCompatDrawableManager mDrawableManager;
      private OnClickListener mNavClickListener;
  
      public RtlToolbar(Context context) {
          this(context, null);
      }
  
      public RtlToolbar(Context context, @Nullable AttributeSet attrs) {
          this(context, attrs, R.attr.toolbarStyle);
      }
  
      public RtlToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
          super(context, attrs, defStyleAttr);
  
          // Need to use getContext() here so that we use the themed context
          final TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,
                  R.styleable.RtlToolbar, defStyleAttr, 0);
  
          mDirection = a.getInteger(R.styleable.RtlToolbar_direction, 0);
  
          if (mDirection == RTL) {
              mContentInsets.setDirection(true);
          }
  
          mTitleFont = a.getString(R.styleable.RtlToolbar_font_path);
          mTitleTextAppearance = a.getResourceId(R.styleable.RtlToolbar_titleTextAppearance, 0);
          mSubtitleTextAppearance = a.getResourceId(R.styleable.RtlToolbar_subtitleTextAppearance, 0);
          mGravity = a.getInteger(R.styleable.Toolbar_android_gravity, mGravity);
          mButtonGravity = Gravity.TOP;
          mTitleMarginStart = mTitleMarginEnd = mTitleMarginTop = mTitleMarginBottom =
                  a.getDimensionPixelOffset(R.styleable.RtlToolbar_titleMargins, 0);
  
          int menu = a.getResourceId(R.styleable.RtlToolbar_optionsMenu, 0);
          if (menu != 0 && !isInEditMode()) {
              inflateMenu(menu);
          }
  
          final int marginStart = a.getDimensionPixelOffset(R.styleable.RtlToolbar_titleMarginStart, -1);
          if (marginStart >= 0) {
              mTitleMarginStart = marginStart;
          }
  
          final int marginEnd = a.getDimensionPixelOffset(R.styleable.RtlToolbar_titleMarginEnd, -1);
          if (marginEnd >= 0) {
              mTitleMarginEnd = marginEnd;
          }
  
          final int marginTop = a.getDimensionPixelOffset(R.styleable.RtlToolbar_titleMarginTop, -1);
          if (marginTop >= 0) {
              mTitleMarginTop = marginTop;
          }
  
          final int marginBottom = a.getDimensionPixelOffset(R.styleable.RtlToolbar_titleMarginBottom,
                  -1);
          if (marginBottom >= 0) {
              mTitleMarginBottom = marginBottom;
          }
  
          mMaxButtonHeight = a.getDimensionPixelSize(R.styleable.RtlToolbar_maxButtonHeight, -1);
  
          final int contentInsetStart =
                  a.getDimensionPixelOffset(R.styleable.RtlToolbar_contentInsetStart,
                          RtlSpacingHelper.UNDEFINED);
          final int contentInsetEnd =
                  a.getDimensionPixelOffset(R.styleable.RtlToolbar_contentInsetEnd,
                          RtlSpacingHelper.UNDEFINED);
          final int contentInsetLeft =
                  a.getDimensionPixelSize(R.styleable.RtlToolbar_contentInsetLeft, 0);
          final int contentInsetRight =
                  a.getDimensionPixelSize(R.styleable.RtlToolbar_contentInsetRight, 0);
  
          mContentInsets.setAbsolute(contentInsetLeft, contentInsetRight);
  
          if (contentInsetStart != RtlSpacingHelper.UNDEFINED ||
                  contentInsetEnd != RtlSpacingHelper.UNDEFINED) {
              mContentInsets.setRelative(contentInsetStart, contentInsetEnd);
          }
  
          mCollapseIcon = a.getDrawable(R.styleable.RtlToolbar_collapseIcon);
          mCollapseDescription = a.getText(R.styleable.RtlToolbar_collapseContentDescription);
  
          final CharSequence title = a.getText(R.styleable.RtlToolbar_title);
          if (!TextUtils.isEmpty(title)) {
              setTitle(title);
          }
  
          final CharSequence subtitle = a.getText(R.styleable.RtlToolbar_subtitle);
          if (!TextUtils.isEmpty(subtitle)) {
              setSubtitle(subtitle);
          }
          // Set the default context, since setPopupTheme() may be a no-op.
          mPopupContext = getContext();
          setPopupTheme(a.getResourceId(R.styleable.RtlToolbar_popupTheme, 0));
  
          final Drawable navIcon = a.getDrawable(R.styleable.RtlToolbar_navigationIcon);
          if (navIcon != null) {
              setNavigationIcon(navIcon);
          }
          final CharSequence navDesc = a.getText(R.styleable.RtlToolbar_navigationContentDescription);
          if (!TextUtils.isEmpty(navDesc)) {
              setNavigationContentDescription(navDesc);
          }
  
          final Drawable logo = a.getDrawable(R.styleable.RtlToolbar_logo);
          if (logo != null) {
              setLogo(logo);
          }
  
          final CharSequence logoDesc = a.getText(R.styleable.RtlToolbar_logoDescription);
          if (!TextUtils.isEmpty(logoDesc)) {
              setLogoDescription(logoDesc);
          }
  
          if (a.hasValue(R.styleable.RtlToolbar_titleTextColor)) {
              setTitleTextColor(a.getColor(R.styleable.RtlToolbar_titleTextColor, 0xffffffff));
          }
  
          if (a.hasValue(R.styleable.RtlToolbar_subtitleTextColor)) {
              setSubtitleTextColor(a.getColor(R.styleable.RtlToolbar_subtitleTextColor, 0xffffffff));
          }
          a.recycle();
  
          mDrawableManager = AppCompatDrawableManager.get();
      }
  
      /**
       * Specifies the theme to use when inflating popup menus. By default, uses
       * the same theme as the toolbar itself.
       *
       * @param resId theme used to inflate popup menus
       * @see #getPopupTheme()
       */
      public void setPopupTheme(@StyleRes int resId) {
          if (mPopupTheme != resId) {
              mPopupTheme = resId;
              if (resId == 0) {
                  mPopupContext = getContext();
              } else {
                  mPopupContext = new ContextThemeWrapper(getContext(), resId);
              }
          }
      }
  
      /**
       * @return resource identifier of the theme used to inflate popup menus, or
       * 0 if menus are inflated against the toolbar theme
       * @see #setPopupTheme(int)
       */
      public int getPopupTheme() {
          return mPopupTheme;
      }
  
      @SuppressWarnings("ResourceType")
      public void onRtlPropertiesChanged(int layoutDirection) {
          if (Build.VERSION.SDK_INT >= 17) {
              super.onRtlPropertiesChanged(layoutDirection);
          }
          mContentInsets.setDirection(layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL);
      }
  
      /**
       * Set a logo drawable from a resource id.
       * <p/>
       * <p>This drawable should generally take the place of title text. The logo cannot be
       * clicked. Apps using a logo should also supply a description using
       * {@link #setLogoDescription(int)}.</p>
       *
       * @param resId ID of a drawable resource
       */
      public void setLogo(@DrawableRes int resId) {
          setLogo(mDrawableManager.getDrawable(getContext(), resId));
      }
  
      /**
       * @hide
       */
      public boolean canShowOverflowMenu() {
          return getVisibility() == VISIBLE && mMenuView != null && mMenuView.isOverflowReserved();
      }
  
      /**
       * Check whether the overflow menu is currently showing. This may not reflect
       * a pending show operation in progress.
       *
       * @return true if the overflow menu is currently showing
       */
      public boolean isOverflowMenuShowing() {
          return mMenuView != null && mMenuView.isOverflowMenuShowing();
      }
  
      /**
       * @hide
       */
      public boolean isOverflowMenuShowPending() {
          return mMenuView != null && mMenuView.isOverflowMenuShowPending();
      }
  
      /**
       * Show the overflow items from the associated menu.
       *
       * @return true if the menu was able to be shown, false otherwise
       */
      public boolean showOverflowMenu() {
          return mMenuView != null && mMenuView.showOverflowMenu();
      }
  
      /**
       * Hide the overflow items from the associated menu.
       *
       * @return true if the menu was able to be hidden, false otherwise
       */
      public boolean hideOverflowMenu() {
          return mMenuView != null && mMenuView.hideOverflowMenu();
      }
  
      /**
       * @hide
       */
      public void setMenu(MenuBuilder menu, ActionMenuPresenter outerPresenter) {
          if (menu == null && mMenuView == null) {
              return;
          }
  
          ensureMenuView();
          final MenuBuilder oldMenu = mMenuView.peekMenu();
          if (oldMenu == menu) {
              return;
          }
  
          if (oldMenu != null) {
              oldMenu.removeMenuPresenter(mOuterActionMenuPresenter);
              oldMenu.removeMenuPresenter(mExpandedMenuPresenter);
          }
  
          if (mExpandedMenuPresenter == null) {
              mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
          }
  
          outerPresenter.setExpandedActionViewsExclusive(true);
          if (menu != null) {
              menu.addMenuPresenter(outerPresenter, mPopupContext);
              menu.addMenuPresenter(mExpandedMenuPresenter, mPopupContext);
          } else {
              outerPresenter.initForMenu(mPopupContext, null);
              mExpandedMenuPresenter.initForMenu(mPopupContext, null);
              outerPresenter.updateMenuView(true);
              mExpandedMenuPresenter.updateMenuView(true);
          }
          mMenuView.setPopupTheme(mPopupTheme);
          mMenuView.setPresenter(outerPresenter);
          mOuterActionMenuPresenter = outerPresenter;
      }
  
      /**
       * Dismiss all currently showing popup menus, including overflow or submenus.
       */
      public void dismissPopupMenus() {
          if (mMenuView != null) {
              mMenuView.dismissPopupMenus();
          }
      }
  
      /**
       * @hide
       */
      public boolean isTitleTruncated() {
          if (mTitleTextView == null) {
              return false;
          }
  
          final Layout titleLayout = mTitleTextView.getLayout();
          if (titleLayout == null) {
              return false;
          }
  
          final int lineCount = titleLayout.getLineCount();
          for (int i = 0; i < lineCount; i++) {
              if (titleLayout.getEllipsisCount(i) > 0) {
                  return true;
              }
          }
          return false;
      }
  
      /**
       * Set a logo drawable.
       * <p/>
       * <p>This drawable should generally take the place of title text. The logo cannot be
       * clicked. Apps using a logo should also supply a description using
       * {@link #setLogoDescription(int)}.</p>
       *
       * @param drawable Drawable to use as a logo
       */
      public void setLogo(Drawable drawable) {
          if (drawable != null) {
              ensureLogoView();
              if (!isChildOrHidden(mLogoView)) {
                  addSystemView(mLogoView, true);
              }
          } else if (mLogoView != null && isChildOrHidden(mLogoView)) {
              removeView(mLogoView);
              mHiddenViews.remove(mLogoView);
          }
          if (mLogoView != null) {
              mLogoView.setImageDrawable(drawable);
          }
      }
  
      /**
       * Return the current logo drawable.
       *
       * @return The current logo drawable
       * @see #setLogo(int)
       * @see #setLogo(Drawable)
       */
      public Drawable getLogo() {
          return mLogoView != null ? mLogoView.getDrawable() : null;
      }
  
      /**
       * Set a description of the toolbar's logo.
       * <p/>
       * <p>This description will be used for accessibility or other similar descriptions
       * of the UI.</p>
       *
       * @param resId String resource id
       */
      public void setLogoDescription(@StringRes int resId) {
          setLogoDescription(getContext().getText(resId));
      }
  
      /**
       * Set a description of the toolbar's logo.
       * <p/>
       * <p>This description will be used for accessibility or other similar descriptions
       * of the UI.</p>
       *
       * @param description Description to set
       */
      public void setLogoDescription(CharSequence description) {
          if (!TextUtils.isEmpty(description)) {
              ensureLogoView();
          }
          if (mLogoView != null) {
              mLogoView.setContentDescription(description);
          }
      }
  
      /**
       * Return the description of the toolbar's logo.
       *
       * @return A description of the logo
       */
      public CharSequence getLogoDescription() {
          return mLogoView != null ? mLogoView.getContentDescription() : null;
      }
  
      private void ensureLogoView() {
          if (mLogoView == null) {
              mLogoView = new ImageView(getContext());
          }
      }
  
      /**
       * Check whether this Toolbar is currently hosting an expanded action view.
       * <p/>
       * <p>An action view may be expanded either directly from the
       * {@link MenuItem MenuItem} it belongs to or by user action. If the Toolbar
       * has an expanded action view it can be collapsed using the {@link #collapseActionView()}
       * method.</p>
       *
       * @return true if the Toolbar has an expanded action view
       */
      public boolean hasExpandedActionView() {
          return mExpandedMenuPresenter != null &&
                  mExpandedMenuPresenter.mCurrentExpandedItem != null;
      }
  
      /**
       * Collapse a currently expanded action view. If this Toolbar does not have an
       * expanded action view this method has no effect.
       * <p/>
       * <p>An action view may be expanded either directly from the
       * {@link MenuItem MenuItem} it belongs to or by user action.</p>
       *
       * @see #hasExpandedActionView()
       */
      public void collapseActionView() {
          final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
                  mExpandedMenuPresenter.mCurrentExpandedItem;
          if (item != null) {
              item.collapseActionView();
          }
      }
  
      /**
       * Returns the title of this toolbar.
       *
       * @return The current title.
       */
      public CharSequence getTitle() {
          return mTitleText;
      }
  
      /**
       * Set the title of this toolbar.
       * <p/>
       * <p>A title should be used as the anchor for a section of content. It should
       * describe or name the content being viewed.</p>
       *
       * @param resId Resource ID of a string to set as the title
       */
      public void setTitle(@StringRes int resId) {
          setTitle(getContext().getText(resId));
      }
  
      /**
       * Set the title of this toolbar.
       * <p/>
       * <p>A title should be used as the anchor for a section of content. It should
       * describe or name the content being viewed.</p>
       *
       * @param title Title to set
       */
      public void setTitle(CharSequence title) {
          if (!TextUtils.isEmpty(title)) {
              if (mTitleTextView == null) {
                  final Context context = getContext();
                  mTitleTextView = new TextView(context);
                  mTitleTextView.setSingleLine();
                  mTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
                  if (mTitleTextAppearance != 0) {
                      mTitleTextView.setTextAppearance(context, mTitleTextAppearance);
                  }
                  if (mTitleTextColor != 0) {
                      mTitleTextView.setTextColor(mTitleTextColor);
                  }
                  if (!TextUtils.isEmpty(mTitleFont) && !isInEditMode()) {
                      if (isAssetExist(mTitleFont)) {
                          Typeface typeface = Typeface.createFromAsset(context.getAssets(), mTitleFont);
                          mTitleTextView.setTypeface(typeface);
                      }
                  }
              }
              if (!isChildOrHidden(mTitleTextView)) {
                  addSystemView(mTitleTextView, true);
              }
          } else if (mTitleTextView != null && isChildOrHidden(mTitleTextView)) {
              removeView(mTitleTextView);
              mHiddenViews.remove(mTitleTextView);
          }
          if (mTitleTextView != null) {
              mTitleTextView.setText(title);
          }
          mTitleText = title;
      }
  
      /**
       * Return the subtitle of this toolbar.
       *
       * @return The current subtitle
       */
      public CharSequence getSubtitle() {
          return mSubtitleText;
      }
  
      /**
       * Set the subtitle of this toolbar.
       * <p/>
       * <p>Subtitles should express extended information about the current content.</p>
       *
       * @param resId String resource ID
       */
      public void setSubtitle(@StringRes int resId) {
          setSubtitle(getContext().getText(resId));
      }
  
      /**
       * Set the subtitle of this toolbar.
       * <p/>
       * <p>Subtitles should express extended information about the current content.</p>
       *
       * @param subtitle Subtitle to set
       */
      public void setSubtitle(CharSequence subtitle) {
          if (!TextUtils.isEmpty(subtitle)) {
              if (mSubtitleTextView == null) {
                  final Context context = getContext();
                  mSubtitleTextView = new TextView(context);
                  mSubtitleTextView.setSingleLine();
                  mSubtitleTextView.setEllipsize(TextUtils.TruncateAt.END);
                  if (mSubtitleTextAppearance != 0) {
                      mSubtitleTextView.setTextAppearance(context, mSubtitleTextAppearance);
                  }
                  if (mSubtitleTextColor != 0) {
                      mSubtitleTextView.setTextColor(mSubtitleTextColor);
                  }
              }
              if (!isChildOrHidden(mSubtitleTextView)) {
                  addSystemView(mSubtitleTextView, true);
              }
          } else if (mSubtitleTextView != null && isChildOrHidden(mSubtitleTextView)) {
              removeView(mSubtitleTextView);
              mHiddenViews.remove(mSubtitleTextView);
          }
          if (mSubtitleTextView != null) {
              mSubtitleTextView.setText(subtitle);
          }
          mSubtitleText = subtitle;
      }
  
      /**
       * Sets the text color, size, style, hint color, and highlight color
       * from the specified TextAppearance resource.
       */
      public void setTitleTextAppearance(Context context, @StyleRes int resId) {
          mTitleTextAppearance = resId;
          if (mTitleTextView != null) {
              mTitleTextView.setTextAppearance(context, resId);
          }
      }
  
      /**
       * Sets the text color, size, style, hint color, and highlight color
       * from the specified TextAppearance resource.
       */
      public void setSubtitleTextAppearance(Context context, @StyleRes int resId) {
          mSubtitleTextAppearance = resId;
          if (mSubtitleTextView != null) {
              mSubtitleTextView.setTextAppearance(context, resId);
          }
      }
  
      /**
       * Sets the text color of the title, if present.
       *
       * @param color The new text color in 0xAARRGGBB format
       */
      public void setTitleTextColor(@ColorInt int color) {
          mTitleTextColor = color;
          if (mTitleTextView != null) {
              mTitleTextView.setTextColor(color);
          }
      }
  
      /**
       * Sets the text color of the subtitle, if present.
       *
       * @param color The new text color in 0xAARRGGBB format
       */
      public void setSubtitleTextColor(@ColorInt int color) {
          mSubtitleTextColor = color;
          if (mSubtitleTextView != null) {
              mSubtitleTextView.setTextColor(color);
          }
      }
  
      /**
       * Retrieve the currently configured content description for the navigation button view.
       * This will be used to describe the navigation action to users through mechanisms such
       * as screen readers or tooltips.
       *
       * @return The navigation button's content description
       */
      @Nullable
      public CharSequence getNavigationContentDescription() {
          return mNavButtonView != null ? mNavButtonView.getContentDescription() : null;
      }
  
      /**
       * Set a content description for the navigation button if one is present. The content
       * description will be read via screen readers or other accessibility systems to explain
       * the action of the navigation button.
       *
       * @param resId Resource ID of a content description string to set, or 0 to
       *              clear the description
       */
      public void setNavigationContentDescription(@StringRes int resId) {
          setNavigationContentDescription(resId != 0 ? getContext().getText(resId) : null);
      }
  
      /**
       * Set a content description for the navigation button if one is present. The content
       * description will be read via screen readers or other accessibility systems to explain
       * the action of the navigation button.
       *
       * @param description Content description to set, or <code>null</code> to
       *                    clear the content description
       */
      public void setNavigationContentDescription(@Nullable CharSequence description) {
          if (!TextUtils.isEmpty(description)) {
              ensureNavButtonView();
          }
          if (mNavButtonView != null) {
              mNavButtonView.setContentDescription(description);
          }
      }
  
      /**
       * Set the icon to use for the toolbar's navigation button.
       * <p/>
       * <p>The navigation button appears at the start of the toolbar if present. Setting an icon
       * will make the navigation button visible.</p>
       * <p/>
       * <p>If you use a navigation icon you should also set a description for its action using
       * {@link #setNavigationContentDescription(int)}. This is used for accessibility and
       * tooltips.</p>
       *
       * @param resId Resource ID of a drawable to set
       */
      public void setNavigationIcon(@DrawableRes int resId) {
          setNavigationIcon(mDrawableManager.getDrawable(getContext(), resId));
      }
  
      /**
       * Set the icon to use for the toolbar's navigation button.
       * <p/>
       * <p>The navigation button appears at the start of the toolbar if present. Setting an icon
       * will make the navigation button visible.</p>
       * <p/>
       * <p>If you use a navigation icon you should also set a description for its action using
       * {@link #setNavigationContentDescription(int)}. This is used for accessibility and
       * tooltips.</p>
       *
       * @param icon Drawable to set, may be null to clear the icon
       */
      public void setNavigationIcon(@Nullable Drawable icon) {
          if (icon != null) {
              ensureNavButtonView();
              if (!isChildOrHidden(mNavButtonView)) {
                  addSystemView(mNavButtonView, true);
              }
          } else if (mNavButtonView != null && isChildOrHidden(mNavButtonView)) {
              removeView(mNavButtonView);
              mHiddenViews.remove(mNavButtonView);
          }
          if (mNavButtonView != null) {
              mNavButtonView.setImageDrawable(icon);
          }
      }
  
      /**
       * Return the current drawable used as the navigation icon.
       *
       * @return The navigation icon drawable
       */
      @Nullable
      public Drawable getNavigationIcon() {
          return mNavButtonView != null ? mNavButtonView.getDrawable() : null;
      }
  
      /**
       * Set a listener to respond to navigation events.
       * <p/>
       * <p>This listener will be called whenever the user clicks the navigation button
       * at the start of the toolbar. An icon must be set for the navigation button to appear.</p>
       *
       * @param listener Listener to set
       * @see #setNavigationIcon(Drawable)
       */
      public void setNavigationOnClickListener(OnClickListener listener) {
          ensureNavButtonView();
          mNavClickListener = listener;
          mNavButtonView.setOnClickListener(listener);
      }
  
      /**
       * Return the Menu shown in the toolbar.
       * <p/>
       * <p>Applications that wish to populate the toolbar's menu can do so from here. To use
       * an XML menu resource, use {@link #inflateMenu(int)}.</p>
       *
       * @return The toolbar's Menu
       */
      public Menu getMenu() {
          ensureMenu();
          return mMenuView.getMenu();
      }
  
      /**
       * Set the icon to use for the overflow button.
       *
       * @param icon Drawable to set, may be null to clear the icon
       */
      public void setOverflowIcon(@Nullable Drawable icon) {
          ensureMenu();
          mMenuView.setOverflowIcon(icon);
      }
  
      /**
       * Return the current drawable used as the overflow icon.
       *
       * @return The overflow icon drawable
       */
      @Nullable
      public Drawable getOverflowIcon() {
          ensureMenu();
          return mMenuView.getOverflowIcon();
      }
  
      private void ensureMenu() {
          ensureMenuView();
          if (mMenuView.peekMenu() == null) {
              // Initialize a new menu for the first time.
              final MenuBuilder menu = (MenuBuilder) mMenuView.getMenu();
              if (mExpandedMenuPresenter == null) {
                  mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
              }
              mMenuView.setExpandedActionViewsExclusive(true);
              menu.addMenuPresenter(mExpandedMenuPresenter, mPopupContext);
          }
      }
  
      private void ensureMenuView() {
          if (mMenuView == null) {
              mMenuView = new ActionMenuView(getContext(), mDirection);
              mMenuView.setPopupTheme(mPopupTheme);
              mMenuView.setOnMenuItemClickListener(mMenuViewItemClickListener);
              mMenuView.setMenuCallbacks(mActionMenuPresenterCallback, mMenuBuilderCallback);
              final LayoutParams lp = generateDefaultLayoutParams();
              lp.gravity = GravityCompat.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
              mMenuView.setLayoutParams(lp);
              addSystemView(mMenuView, false);
          }
      }
  
      private MenuInflater getMenuInflater() {
          return new SupportMenuInflater(getContext());
      }
  
      /**
       * Inflate a menu resource into this toolbar.
       * <p/>
       * <p>Inflate an XML menu resource into this toolbar. Existing items in the menu will not
       * be modified or removed.</p>
       *
       * @param resId ID of a menu resource to inflate
       */
      public void inflateMenu(@MenuRes int resId) {
          getMenuInflater().inflate(resId, getMenu());
      }
  
      /**
       * Set a listener to respond to menu item click events.
       * <p/>
       * <p>This listener will be invoked whenever a user selects a menu item from
       * the action buttons presented at the end of the toolbar or the associated overflow.</p>
       *
       * @param listener Listener to set
       */
      public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
          mOnMenuItemClickListener = listener;
      }
  
      /**
       * Set the content insets for this toolbar relative to layout direction.
       * <p/>
       * <p>The content inset affects the valid area for Toolbar content other than
       * the navigation button and menu. Insets define the minimum margin for these components
       * and can be used to effectively align Toolbar content along well-known gridlines.</p>
       *
       * @param contentInsetStart Content inset for the toolbar starting edge
       * @param contentInsetEnd   Content inset for the toolbar ending edge
       * @see #setContentInsetsAbsolute(int, int)
       * @see #getContentInsetStart()
       * @see #getContentInsetEnd()
       * @see #getContentInsetLeft()
       * @see #getContentInsetRight()
       */
      public void setContentInsetsRelative(int contentInsetStart, int contentInsetEnd) {
          mContentInsets.setRelative(contentInsetStart, contentInsetEnd);
      }
  
      /**
       * Get the starting content inset for this toolbar.
       * <p/>
       * <p>The content inset affects the valid area for Toolbar content other than
       * the navigation button and menu. Insets define the minimum margin for these components
       * and can be used to effectively align Toolbar content along well-known gridlines.</p>
       *
       * @return The starting content inset for this toolbar
       * @see #setContentInsetsRelative(int, int)
       * @see #setContentInsetsAbsolute(int, int)
       * @see #getContentInsetEnd()
       * @see #getContentInsetLeft()
       * @see #getContentInsetRight()
       */
      public int getContentInsetStart() {
          return mContentInsets.getStart();
      }
  
      /**
       * Get the ending content inset for this toolbar.
       * <p/>
       * <p>The content inset affects the valid area for Toolbar content other than
       * the navigation button and menu. Insets define the minimum margin for these components
       * and can be used to effectively align Toolbar content along well-known gridlines.</p>
       *
       * @return The ending content inset for this toolbar
       * @see #setContentInsetsRelative(int, int)
       * @see #setContentInsetsAbsolute(int, int)
       * @see #getContentInsetStart()
       * @see #getContentInsetLeft()
       * @see #getContentInsetRight()
       */
      public int getContentInsetEnd() {
          return mContentInsets.getEnd();
      }
  
      /**
       * Set the content insets for this toolbar.
       * <p/>
       * <p>The content inset affects the valid area for Toolbar content other than
       * the navigation button and menu. Insets define the minimum margin for these components
       * and can be used to effectively align Toolbar content along well-known gridlines.</p>
       *
       * @param contentInsetLeft  Content inset for the toolbar's left edge
       * @param contentInsetRight Content inset for the toolbar's right edge
       * @see #setContentInsetsAbsolute(int, int)
       * @see #getContentInsetStart()
       * @see #getContentInsetEnd()
       * @see #getContentInsetLeft()
       * @see #getContentInsetRight()
       */
      public void setContentInsetsAbsolute(int contentInsetLeft, int contentInsetRight) {
          mContentInsets.setAbsolute(contentInsetLeft, contentInsetRight);
      }
  
      /**
       * Get the left content inset for this toolbar.
       * <p/>
       * <p>The content inset affects the valid area for Toolbar content other than
       * the navigation button and menu. Insets define the minimum margin for these components
       * and can be used to effectively align Toolbar content along well-known gridlines.</p>
       *
       * @return The left content inset for this toolbar
       * @see #setContentInsetsRelative(int, int)
       * @see #setContentInsetsAbsolute(int, int)
       * @see #getContentInsetStart()
       * @see #getContentInsetEnd()
       * @see #getContentInsetRight()
       */
      public int getContentInsetLeft() {
          return mContentInsets.getLeft();
      }
  
      /**
       * Get the right content inset for this toolbar.
       * <p/>
       * <p>The content inset affects the valid area for Toolbar content other than
       * the navigation button and menu. Insets define the minimum margin for these components
       * and can be used to effectively align Toolbar content along well-known gridlines.</p>
       *
       * @return The right content inset for this toolbar
       * @see #setContentInsetsRelative(int, int)
       * @see #setContentInsetsAbsolute(int, int)
       * @see #getContentInsetStart()
       * @see #getContentInsetEnd()
       * @see #getContentInsetLeft()
       */
      public int getContentInsetRight() {
          return mContentInsets.getRight();
      }
  
      private void ensureNavButtonView() {
          if (mNavButtonView == null) {
              mNavButtonView = new ImageButton(getContext(), null,
                      R.attr.toolbarNavigationButtonStyle);
              final LayoutParams lp = generateDefaultLayoutParams();
              lp.gravity = GravityCompat.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
              mNavButtonView.setLayoutParams(lp);
              if (mNavClickListener == null)
                  setNavigationOnClickListener();
          }
      }
  
      private void setNavigationOnClickListener() {
          mNavButtonView.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View v) {
                  if (mOnMenuItemClickListener != null) {
                      ActionMenuItem menuItem = new ActionMenuItem(getContext(), 0,
                              android.R.id.home, 0, 0, mTitleText);
                      mOnMenuItemClickListener.onMenuItemClick(menuItem);
                  }
              }
          });
      }
  
      private void ensureCollapseButtonView() {
          if (mCollapseButtonView == null) {
              mCollapseButtonView = new ImageButton(getContext(), null,
                      R.attr.toolbarNavigationButtonStyle);
              mCollapseButtonView.setImageDrawable(mCollapseIcon);
              mCollapseButtonView.setContentDescription(mCollapseDescription);
              final LayoutParams lp = generateDefaultLayoutParams();
              lp.gravity = GravityCompat.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
              lp.mViewType = LayoutParams.EXPANDED;
              mCollapseButtonView.setLayoutParams(lp);
              mCollapseButtonView.setOnClickListener(new OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      collapseActionView();
                  }
              });
          }
      }
  
      private void addSystemView(View v, boolean allowHide) {
          final ViewGroup.LayoutParams vlp = v.getLayoutParams();
          final LayoutParams lp;
          if (vlp == null) {
              lp = generateDefaultLayoutParams();
          } else if (!checkLayoutParams(vlp)) {
              lp = generateLayoutParams(vlp);
          } else {
              lp = (LayoutParams) vlp;
          }
          lp.mViewType = LayoutParams.SYSTEM;
  
          if (allowHide && mExpandedActionView != null) {
              v.setLayoutParams(lp);
              mHiddenViews.add(v);
          } else {
              addView(v, lp);
          }
      }
  
      @Override
      protected Parcelable onSaveInstanceState() {
          SavedState state = new SavedState(super.onSaveInstanceState());
  
          if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) {
              state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId();
          }
  
          state.isOverflowOpen = isOverflowMenuShowing();
          return state;
      }
  
      @Override
      protected void onRestoreInstanceState(Parcelable state) {
          final SavedState ss = (SavedState) state;
          super.onRestoreInstanceState(ss.getSuperState());
  
          final Menu menu = mMenuView != null ? mMenuView.peekMenu() : null;
          if (ss.expandedMenuItemId != 0 && mExpandedMenuPresenter != null && menu != null) {
              final MenuItem item = menu.findItem(ss.expandedMenuItemId);
              if (item != null) {
                  MenuItemCompat.expandActionView(item);
              }
          }
  
          if (ss.isOverflowOpen) {
              postShowOverflowMenu();
          }
      }
  
      private void postShowOverflowMenu() {
          removeCallbacks(mShowOverflowMenuRunnable);
          post(mShowOverflowMenuRunnable);
      }
  
      @Override
      protected void onDetachedFromWindow() {
          super.onDetachedFromWindow();
          removeCallbacks(mShowOverflowMenuRunnable);
      }
  
      @Override
      public boolean onTouchEvent(MotionEvent ev) {
          // Toolbars always eat touch events, but should still respect the touch event dispatch
          // contract. If the normal View implementation doesn't want the events, we'll just silently
          // eat the rest of the gesture without reporting the events to the default implementation
          // since that's what it expects.
  
          final int action = MotionEventCompat.getActionMasked(ev);
          if (action == MotionEvent.ACTION_DOWN) {
              mEatingTouch = false;
          }
  
          if (!mEatingTouch) {
              final boolean handled = super.onTouchEvent(ev);
              if (action == MotionEvent.ACTION_DOWN && !handled) {
                  mEatingTouch = true;
              }
          }
  
          if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
              mEatingTouch = false;
          }
  
          return true;
      }
  
      @Override
      public boolean onHoverEvent(MotionEvent ev) {
          // Same deal as onTouchEvent() above. Eat all hover events, but still
          // respect the touch event dispatch contract.
  
          final int action = MotionEventCompat.getActionMasked(ev);
          if (action == MotionEvent.ACTION_HOVER_ENTER) {
              mEatingHover = false;
          }
  
          if (!mEatingHover) {
              final boolean handled = super.onHoverEvent(ev);
              if (action == MotionEvent.ACTION_HOVER_ENTER && !handled) {
                  mEatingHover = true;
              }
          }
  
          if (action == MotionEvent.ACTION_HOVER_EXIT || action == MotionEvent.ACTION_CANCEL) {
              mEatingHover = false;
          }
  
          return true;
      }
  
      private void measureChildConstrained(View child, int parentWidthSpec, int widthUsed,
                                           int parentHeightSpec, int heightUsed, int heightConstraint) {
          final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
  
          int childWidthSpec = getChildMeasureSpec(parentWidthSpec,
                  getPaddingLeft() + getPaddingRight() + lp.leftMargin + lp.rightMargin
                          + widthUsed, lp.width);
          int childHeightSpec = getChildMeasureSpec(parentHeightSpec,
                  getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin
                          + heightUsed, lp.height);
  
          final int childHeightMode = MeasureSpec.getMode(childHeightSpec);
          if (childHeightMode != MeasureSpec.EXACTLY && heightConstraint >= 0) {
              final int size = childHeightMode != MeasureSpec.UNSPECIFIED ?
                      Math.min(MeasureSpec.getSize(childHeightSpec), heightConstraint) :
                      heightConstraint;
              childHeightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
          }
          child.measure(childWidthSpec, childHeightSpec);
      }
  
      /**
       * Returns the width + uncollapsed margins
       */
      private int measureChildCollapseMargins(View child,
                                              int parentWidthMeasureSpec, int widthUsed,
                                              int parentHeightMeasureSpec, int heightUsed, int[] collapsingMargins) {
          final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
  
          final int leftDiff = lp.leftMargin - collapsingMargins[0];
          final int rightDiff = lp.rightMargin - collapsingMargins[1];
          final int leftMargin = Math.max(0, leftDiff);
          final int rightMargin = Math.max(0, rightDiff);
          final int hMargins = leftMargin + rightMargin;
          collapsingMargins[0] = Math.max(0, -leftDiff);
          collapsingMargins[1] = Math.max(0, -rightDiff);
  
          final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
                  getPaddingLeft() + getPaddingRight() + hMargins + widthUsed, lp.width);
          final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
                  getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin
                          + heightUsed, lp.height);
  
          child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
          return child.getMeasuredWidth() + hMargins;
      }
  
      /**
       * Returns true if the Toolbar is collapsible and has no child views with a measured size > 0.
       */
      private boolean shouldCollapse() {
          if (!mCollapsible) return false;
  
          final int childCount = getChildCount();
          for (int i = 0; i < childCount; i++) {
              final View child = getChildAt(i);
              if (shouldLayout(child) && child.getMeasuredWidth() > 0 &&
                      child.getMeasuredHeight() > 0) {
                  return false;
              }
          }
          return true;
      }
  
      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          int width = 0;
          int height = 0;
          int childState = 0;
  
          final int[] collapsingMargins = mTempMargins;
          final int marginStartIndex;
          final int marginEndIndex;
          if (ViewUtils.isLayoutRtl(this)) {
              marginStartIndex = 1;
              marginEndIndex = 0;
          } else {
              marginStartIndex = 0;
              marginEndIndex = 1;
          }
  
          // System views measure first.
  
          int navWidth = 0;
          if (shouldLayout(mNavButtonView)) {
              measureChildConstrained(mNavButtonView, widthMeasureSpec, width, heightMeasureSpec, 0,
                      mMaxButtonHeight);
              navWidth = mNavButtonView.getMeasuredWidth() + getHorizontalMargins(mNavButtonView);
              height = Math.max(height, mNavButtonView.getMeasuredHeight() +
                      getVerticalMargins(mNavButtonView));
              childState = View.combineMeasuredStates(childState,
                      ViewCompat.getMeasuredState(mNavButtonView));
          }
  
          if (shouldLayout(mCollapseButtonView)) {
              measureChildConstrained(mCollapseButtonView, widthMeasureSpec, width,
                      heightMeasureSpec, 0, mMaxButtonHeight);
              navWidth = mCollapseButtonView.getMeasuredWidth() +
                      getHorizontalMargins(mCollapseButtonView);
              height = Math.max(height, mCollapseButtonView.getMeasuredHeight() +
                      getVerticalMargins(mCollapseButtonView));
              childState = View.combineMeasuredStates(childState,
                      ViewCompat.getMeasuredState(mCollapseButtonView));
          }
  
          final int contentInsetStart = getContentInsetStart();
          width += Math.max(contentInsetStart, navWidth);
          collapsingMargins[marginStartIndex] = Math.max(0, contentInsetStart - navWidth);
  
          int menuWidth = 0;
          if (shouldLayout(mMenuView)) {
              measureChildConstrained(mMenuView, widthMeasureSpec, width, heightMeasureSpec, 0,
                      mMaxButtonHeight);
              menuWidth = mMenuView.getMeasuredWidth() + getHorizontalMargins(mMenuView);
              height = Math.max(height, mMenuView.getMeasuredHeight() +
                      getVerticalMargins(mMenuView));
              childState = View.combineMeasuredStates(childState,
                      ViewCompat.getMeasuredState(mMenuView));
          }
  
          final int contentInsetEnd = getContentInsetEnd();
          width += Math.max(contentInsetEnd, menuWidth);
          collapsingMargins[marginEndIndex] = Math.max(0, contentInsetEnd - menuWidth);
  
          if (shouldLayout(mExpandedActionView)) {
              width += measureChildCollapseMargins(mExpandedActionView, widthMeasureSpec, width,
                      heightMeasureSpec, 0, collapsingMargins);
              height = Math.max(height, mExpandedActionView.getMeasuredHeight() +
                      getVerticalMargins(mExpandedActionView));
              childState = View.combineMeasuredStates(childState,
                      ViewCompat.getMeasuredState(mExpandedActionView));
          }
  
          if (shouldLayout(mLogoView)) {
              width += measureChildCollapseMargins(mLogoView, widthMeasureSpec, width,
                      heightMeasureSpec, 0, collapsingMargins);
              height = Math.max(height, mLogoView.getMeasuredHeight() +
                      getVerticalMargins(mLogoView));
              childState = View.combineMeasuredStates(childState,
                      ViewCompat.getMeasuredState(mLogoView));
          }
  
          final int childCount = getChildCount();
          for (int i = 0; i < childCount; i++) {
              final View child = getChildAt(i);
              final LayoutParams lp = (LayoutParams) child.getLayoutParams();
              if (lp.mViewType != LayoutParams.CUSTOM || !shouldLayout(child)) {
                  // We already got all system views above. Skip them and GONE views.
                  continue;
              }
  
              width += measureChildCollapseMargins(child, widthMeasureSpec, width,
                      heightMeasureSpec, 0, collapsingMargins);
              height = Math.max(height, child.getMeasuredHeight() + getVerticalMargins(child));
              childState = View.combineMeasuredStates(childState,
                      ViewCompat.getMeasuredState(child));
          }
  
          int titleWidth = 0;
          int titleHeight = 0;
          final int titleVertMargins = mTitleMarginTop + mTitleMarginBottom;
          final int titleHorizMargins = mTitleMarginStart + mTitleMarginEnd;
          if (shouldLayout(mTitleTextView)) {
              titleWidth = measureChildCollapseMargins(mTitleTextView, widthMeasureSpec,
                      width + titleHorizMargins, heightMeasureSpec, titleVertMargins,
                      collapsingMargins);
              titleWidth = mTitleTextView.getMeasuredWidth() + getHorizontalMargins(mTitleTextView);
              titleHeight = mTitleTextView.getMeasuredHeight() + getVerticalMargins(mTitleTextView);
              childState = View.combineMeasuredStates(childState,
                      ViewCompat.getMeasuredState(mTitleTextView));
          }
          if (shouldLayout(mSubtitleTextView)) {
              titleWidth = Math.max(titleWidth, measureChildCollapseMargins(mSubtitleTextView,
                      widthMeasureSpec, width + titleHorizMargins,
                      heightMeasureSpec, titleHeight + titleVertMargins,
                      collapsingMargins));
              titleHeight += mSubtitleTextView.getMeasuredHeight() +
                      getVerticalMargins(mSubtitleTextView);
              childState = View.combineMeasuredStates(childState,
                      ViewCompat.getMeasuredState(mSubtitleTextView));
          }
  
          width += titleWidth;
          height = Math.max(height, titleHeight);
  
          // Measurement already took padding into account for available space for the children,
          // add it in for the final size.
          width += getPaddingLeft() + getPaddingRight();
          height += getPaddingTop() + getPaddingBottom();
  
          final int measuredWidth = ViewCompat.resolveSizeAndState(
                  Math.max(width, getSuggestedMinimumWidth()),
                  widthMeasureSpec, childState & ViewCompat.MEASURED_STATE_MASK);
          final int measuredHeight = ViewCompat.resolveSizeAndState(
                  Math.max(height, getSuggestedMinimumHeight()),
                  heightMeasureSpec, childState << ViewCompat.MEASURED_HEIGHT_STATE_SHIFT);
  
          setMeasuredDimension(measuredWidth, shouldCollapse() ? 0 : measuredHeight);
      }
  
      @Override
      protected void onLayout(boolean changed, int l, int t, int r, int b) {
          final boolean isRtl = isRtl();
          final int width = getWidth();
          final int height = getHeight();
          final int paddingLeft = getPaddingLeft();
          final int paddingRight = getPaddingRight();
          final int paddingTop = getPaddingTop();
          final int paddingBottom = getPaddingBottom();
          int left = paddingLeft;
          int right = width - paddingRight;
  
          final int[] collapsingMargins = mTempMargins;
          collapsingMargins[0] = collapsingMargins[1] = 0;
  
          // Align views within the minimum toolbar height, if set.
          final int alignmentHeight = ViewCompat.getMinimumHeight(this);
  
          if (shouldLayout(mNavButtonView)) {
              if (isRtl) {
                  right = layoutChildRight(mNavButtonView, right, collapsingMargins,
                          alignmentHeight);
              } else {
                  left = layoutChildLeft(mNavButtonView, left, collapsingMargins,
                          alignmentHeight);
              }
          }
  
          if (shouldLayout(mCollapseButtonView)) {
              if (isRtl) {
                  right = layoutChildRight(mCollapseButtonView, right, collapsingMargins,
                          alignmentHeight);
              } else {
                  left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins,
                          alignmentHeight);
              }
          }
  
          if (shouldLayout(mMenuView)) {
              if (isRtl) {
                  left = layoutChildLeft(mMenuView, left, collapsingMargins,
                          alignmentHeight);
              } else {
                  right = layoutChildRight(mMenuView, right, collapsingMargins,
                          alignmentHeight);
              }
          }
  
          collapsingMargins[0] = Math.max(0, getContentInsetLeft() - left);
          collapsingMargins[1] = Math.max(0, getContentInsetRight() - (width - paddingRight - right));
          left = Math.max(left, getContentInsetLeft());
          right = Math.min(right, width - paddingRight - getContentInsetRight());
  
          if (shouldLayout(mExpandedActionView)) {
              if (isRtl) {
                  right = layoutChildRight(mExpandedActionView, right, collapsingMargins,
                          alignmentHeight);
              } else {
                  left = layoutChildLeft(mExpandedActionView, left, collapsingMargins,
                          alignmentHeight);
              }
          }
  
          if (shouldLayout(mLogoView)) {
              if (isRtl) {
                  right = layoutChildRight(mLogoView, right, collapsingMargins,
                          alignmentHeight);
              } else {
                  left = layoutChildLeft(mLogoView, left, collapsingMargins,
                          alignmentHeight);
              }
          }
  
          final boolean layoutTitle = shouldLayout(mTitleTextView);
          final boolean layoutSubtitle = shouldLayout(mSubtitleTextView);
          int titleHeight = 0;
          if (layoutTitle) {
              final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
              titleHeight += lp.topMargin + mTitleTextView.getMeasuredHeight() + lp.bottomMargin;
          }
          if (layoutSubtitle) {
              final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams();
              titleHeight += lp.topMargin + mSubtitleTextView.getMeasuredHeight() + lp.bottomMargin;
          }
  
          if (layoutTitle || layoutSubtitle) {
              int titleTop;
              final View topChild = layoutTitle ? mTitleTextView : mSubtitleTextView;
              final View bottomChild = layoutSubtitle ? mSubtitleTextView : mTitleTextView;
              final LayoutParams toplp = (LayoutParams) topChild.getLayoutParams();
              final LayoutParams bottomlp = (LayoutParams) bottomChild.getLayoutParams();
              final boolean titleHasWidth = layoutTitle && mTitleTextView.getMeasuredWidth() > 0
                      || layoutSubtitle && mSubtitleTextView.getMeasuredWidth() > 0;
  
              switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) {
                  case Gravity.TOP:
                      titleTop = getPaddingTop() + toplp.topMargin + mTitleMarginTop;
                      break;
                  default:
                  case Gravity.CENTER_VERTICAL:
                      final int space = height - paddingTop - paddingBottom;
                      int spaceAbove = (space - titleHeight) / 2;
                      if (spaceAbove < toplp.topMargin + mTitleMarginTop) {
                          spaceAbove = toplp.topMargin + mTitleMarginTop;
                      } else {
                          final int spaceBelow = height - paddingBottom - titleHeight -
                                  spaceAbove - paddingTop;
                          if (spaceBelow < toplp.bottomMargin + mTitleMarginBottom) {
                              spaceAbove = Math.max(0, spaceAbove -
                                      (bottomlp.bottomMargin + mTitleMarginBottom - spaceBelow));
                          }
                      }
                      titleTop = paddingTop + spaceAbove;
                      break;
                  case Gravity.BOTTOM:
                      titleTop = height - paddingBottom - bottomlp.bottomMargin - mTitleMarginBottom -
                              titleHeight;
                      break;
              }
              if (isRtl) {
                  final int rd = (titleHasWidth ? mTitleMarginStart : 0) - collapsingMargins[1];
                  right -= Math.max(0, rd);
                  collapsingMargins[1] = Math.max(0, -rd);
                  int titleRight = right;
                  int subtitleRight = right;
  
                  if (layoutTitle) {
                      final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
                      final int titleLeft = titleRight - mTitleTextView.getMeasuredWidth();
                      final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
                      mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
                      titleRight = titleLeft - mTitleMarginEnd;
                      titleTop = titleBottom + lp.bottomMargin;
                  }
                  if (layoutSubtitle) {
                      final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams();
                      titleTop += lp.topMargin;
                      final int subtitleLeft = subtitleRight - mSubtitleTextView.getMeasuredWidth();
                      final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight();
                      mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom);
                      subtitleRight = subtitleRight - mTitleMarginEnd;
                      titleTop = subtitleBottom + lp.bottomMargin;
                  }
                  if (titleHasWidth) {
                      right = Math.min(titleRight, subtitleRight);
                  }
              } else {
                  final int ld = (titleHasWidth ? mTitleMarginStart : 0) - collapsingMargins[0];
                  left += Math.max(0, ld);
                  collapsingMargins[0] = Math.max(0, -ld);
                  int titleLeft = left;
                  int subtitleLeft = left;
  
                  if (layoutTitle) {
                      final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
                      final int titleRight = titleLeft + mTitleTextView.getMeasuredWidth();
                      final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
                      mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
                      titleLeft = titleRight + mTitleMarginEnd;
                      titleTop = titleBottom + lp.bottomMargin;
                  }
                  if (layoutSubtitle) {
                      final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams();
                      titleTop += lp.topMargin;
                      final int subtitleRight = subtitleLeft + mSubtitleTextView.getMeasuredWidth();
                      final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight();
                      mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom);
                      subtitleLeft = subtitleRight + mTitleMarginEnd;
                      titleTop = subtitleBottom + lp.bottomMargin;
                  }
                  if (titleHasWidth) {
                      left = Math.max(titleLeft, subtitleLeft);
                  }
              }
          }
  
          // Get all remaining children sorted for layout. This is all prepared
          // such that absolute layout direction can be used below.
  
          addCustomViewsWithGravity(mTempViews, Gravity.LEFT);
          final int leftViewsCount = mTempViews.size();
          for (int i = 0; i < leftViewsCount; i++) {
              left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins,
                      alignmentHeight);
          }
  
          addCustomViewsWithGravity(mTempViews, Gravity.RIGHT);
          final int rightViewsCount = mTempViews.size();
          for (int i = 0; i < rightViewsCount; i++) {
              right = layoutChildRight(mTempViews.get(i), right, collapsingMargins,
                      alignmentHeight);
          }
  
          // Centered views try to center with respect to the whole bar, but views pinned
          // to the left or right can push the mass of centered views to one side or the other.
          addCustomViewsWithGravity(mTempViews, Gravity.CENTER_HORIZONTAL);
          final int centerViewsWidth = getViewListMeasuredWidth(mTempViews, collapsingMargins);
          final int parentCenter = paddingLeft + (width - paddingLeft - paddingRight) / 2;
          final int halfCenterViewsWidth = centerViewsWidth / 2;
          int centerLeft = parentCenter - halfCenterViewsWidth;
          final int centerRight = centerLeft + centerViewsWidth;
          if (centerLeft < left) {
              centerLeft = left;
          } else if (centerRight > right) {
              centerLeft -= centerRight - right;
          }
  
          final int centerViewsCount = mTempViews.size();
          for (int i = 0; i < centerViewsCount; i++) {
              centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins,
                      alignmentHeight);
          }
  
          mTempViews.clear();
      }
  
      private int getViewListMeasuredWidth(List<View> views, int[] collapsingMargins) {
          int collapseLeft = collapsingMargins[0];
          int collapseRight = collapsingMargins[1];
          int width = 0;
          final int count = views.size();
          for (int i = 0; i < count; i++) {
              final View v = views.get(i);
              final LayoutParams lp = (LayoutParams) v.getLayoutParams();
              final int l = lp.leftMargin - collapseLeft;
              final int r = lp.rightMargin - collapseRight;
              final int leftMargin = Math.max(0, l);
              final int rightMargin = Math.max(0, r);
              collapseLeft = Math.max(0, -l);
              collapseRight = Math.max(0, -r);
              width += leftMargin + v.getMeasuredWidth() + rightMargin;
          }
          return width;
      }
  
      private int layoutChildLeft(View child, int left, int[] collapsingMargins,
                                  int alignmentHeight) {
          final LayoutParams lp = (LayoutParams) child.getLayoutParams();
          final int l = lp.leftMargin - collapsingMargins[0];
          left += Math.max(0, l);
          collapsingMargins[0] = Math.max(0, -l);
          final int top = getChildTop(child, alignmentHeight);
          final int childWidth = child.getMeasuredWidth();
          child.layout(left, top, left + childWidth, top + child.getMeasuredHeight());
          left += childWidth + lp.rightMargin;
          return left;
      }
  
      private int layoutChildRight(View child, int right, int[] collapsingMargins,
                                   int alignmentHeight) {
          final LayoutParams lp = (LayoutParams) child.getLayoutParams();
          final int r = lp.rightMargin - collapsingMargins[1];
          right -= Math.max(0, r);
          collapsingMargins[1] = Math.max(0, -r);
          final int top = getChildTop(child, alignmentHeight);
          final int childWidth = child.getMeasuredWidth();
          child.layout(right - childWidth, top, right, top + child.getMeasuredHeight());
          right -= childWidth + lp.leftMargin;
          return right;
      }
  
      private int getChildTop(View child, int alignmentHeight) {
          final LayoutParams lp = (LayoutParams) child.getLayoutParams();
          final int childHeight = child.getMeasuredHeight();
          final int alignmentOffset = alignmentHeight > 0 ? (childHeight - alignmentHeight) / 2 : 0;
          switch (getChildVerticalGravity(lp.gravity)) {
              case Gravity.TOP:
                  return getPaddingTop() - alignmentOffset;
  
              case Gravity.BOTTOM:
                  return getHeight() - getPaddingBottom() - childHeight
                          - lp.bottomMargin - alignmentOffset;
  
              default:
              case Gravity.CENTER_VERTICAL:
                  final int paddingTop = getPaddingTop();
                  final int paddingBottom = getPaddingBottom();
                  final int height = getHeight();
                  final int space = height - paddingTop - paddingBottom;
                  int spaceAbove = (space - childHeight) / 2;
                  if (spaceAbove < lp.topMargin) {
                      spaceAbove = lp.topMargin;
                  } else {
                      final int spaceBelow = height - paddingBottom - childHeight -
                              spaceAbove - paddingTop;
                      if (spaceBelow < lp.bottomMargin) {
                          spaceAbove = Math.max(0, spaceAbove - (lp.bottomMargin - spaceBelow));
                      }
                  }
                  return paddingTop + spaceAbove;
          }
      }
  
      private int getChildVerticalGravity(int gravity) {
          final int vgrav = gravity & Gravity.VERTICAL_GRAVITY_MASK;
          switch (vgrav) {
              case Gravity.TOP:
              case Gravity.BOTTOM:
              case Gravity.CENTER_VERTICAL:
                  return vgrav;
              default:
                  return mGravity & Gravity.VERTICAL_GRAVITY_MASK;
          }
      }
  
      /**
       * Prepare a list of non-SYSTEM child views. If the layout direction is RTL
       * this will be in reverse child order.
       *
       * @param views   List to populate. It will be cleared before use.
       * @param gravity Horizontal gravity to match against
       */
      private void addCustomViewsWithGravity(List<View> views, int gravity) {
          final boolean isRtl = isRtl();
          final int childCount = getChildCount();
          final int absGrav = GravityCompat.getAbsoluteGravity(gravity, getDirectionLayout());
  
          views.clear();
  
          if (isRtl) {
              for (int i = childCount - 1; i >= 0; i--) {
                  final View child = getChildAt(i);
                  final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                  if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
                          getChildHorizontalGravity(lp.gravity) == absGrav) {
                      views.add(child);
                  }
              }
          } else {
              for (int i = 0; i < childCount; i++) {
                  final View child = getChildAt(i);
                  final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                  if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
                          getChildHorizontalGravity(lp.gravity) == absGrav) {
                      views.add(child);
                  }
              }
          }
      }
  
      private int getChildHorizontalGravity(int gravity) {
          final int ld = getDirectionLayout();
          final int absGrav = GravityCompat.getAbsoluteGravity(gravity, ld);
          final int hGrav = absGrav & Gravity.HORIZONTAL_GRAVITY_MASK;
          switch (hGrav) {
              case Gravity.LEFT:
              case Gravity.RIGHT:
              case Gravity.CENTER_HORIZONTAL:
                  return hGrav;
              default:
                  return ld == ViewCompat.LAYOUT_DIRECTION_RTL ? Gravity.RIGHT : Gravity.LEFT;
          }
      }
  
      private boolean shouldLayout(View view) {
          return view != null && view.getParent() == this && view.getVisibility() != GONE;
      }
  
      private int getHorizontalMargins(View v) {
          final MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
          return MarginLayoutParamsCompat.getMarginStart(mlp) +
                  MarginLayoutParamsCompat.getMarginEnd(mlp);
      }
  
      private int getVerticalMargins(View v) {
          final MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
          return mlp.topMargin + mlp.bottomMargin;
      }
  
      @Override
      public LayoutParams generateLayoutParams(AttributeSet attrs) {
          return new LayoutParams(getContext(), attrs);
      }
  
      @Override
      protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
          if (p instanceof LayoutParams) {
              return new LayoutParams((LayoutParams) p);
          } else if (p instanceof ActionBar.LayoutParams) {
              return new LayoutParams((ActionBar.LayoutParams) p);
          } else if (p instanceof MarginLayoutParams) {
              return new LayoutParams((MarginLayoutParams) p);
          } else {
              return new LayoutParams(p);
          }
      }
  
      @Override
      protected LayoutParams generateDefaultLayoutParams() {
          return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
      }
  
      @Override
      protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
          return super.checkLayoutParams(p) && p instanceof LayoutParams;
      }
  
      private static boolean isCustomView(View child) {
          return ((LayoutParams) child.getLayoutParams()).mViewType == LayoutParams.CUSTOM;
      }
  
      /**
       * @hide
       */
      public DecorToolbar getWrapper() {
          if (mWrapper == null) {
              mWrapper = new ToolbarWidgetWrapper(this, true, mDirection);
          }
          return mWrapper;
      }
  
      void removeChildrenForExpandedActionView() {
          final int childCount = getChildCount();
          // Go backwards since we're removing from the list
          for (int i = childCount - 1; i >= 0; i--) {
              final View child = getChildAt(i);
              final LayoutParams lp = (LayoutParams) child.getLayoutParams();
              if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
                  removeViewAt(i);
                  mHiddenViews.add(child);
              }
          }
      }
  
      void addChildrenForExpandedActionView() {
          final int count = mHiddenViews.size();
          // Re-add in reverse order since we removed in reverse order
          for (int i = count - 1; i >= 0; i--) {
              addView(mHiddenViews.get(i));
          }
          mHiddenViews.clear();
      }
  
      private boolean isChildOrHidden(View child) {
          return child.getParent() == this || mHiddenViews.contains(child);
      }
  
      /**
       * Force the toolbar to collapse to zero-height during measurement if
       * it could be considered "empty" (no visible elements with nonzero measured size)
       *
       * @hide
       */
      public void setCollapsible(boolean collapsible) {
          mCollapsible = collapsible;
          requestLayout();
      }
  
      /**
       * Must be called before the menu is accessed
       *
       * @hide
       */
      public void setMenuCallbacks(MenuPresenter.Callback pcb, MenuBuilder.Callback mcb) {
          mActionMenuPresenterCallback = pcb;
          mMenuBuilderCallback = mcb;
      }
  
      private boolean isRtl() {
          switch (mDirection) {
              case RTL:
                  return true;
              case LTR:
                  return false;
              default:
                  return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
          }
      }
  
      private int getDirectionLayout() {
          switch (mDirection) {
              case RTL:
                  return ViewCompat.LAYOUT_DIRECTION_RTL;
              case LTR:
                  return ViewCompat.LAYOUT_DIRECTION_LTR;
              default:
                  return ViewCompat.getLayoutDirection(this);
          }
      }
  
      public int getDirection() {
          return mDirection;
      }
  
      public int getGravity() {
          switch (mDirection) {
              case RTL:
                  return Gravity.RIGHT;
              case LTR:
                  return Gravity.LEFT;
              default:
                  return Gravity.START;
          }
      }
  
      private boolean isAssetExist(String asset) {
          AssetManager assetManager = getResources().getAssets();
          InputStream inputStream = null;
          boolean exist = false;
          try {
              inputStream = assetManager.open(asset);
              exist = true;
          } catch (IOException ex) {
              ex.printStackTrace();
          } finally {
              if (inputStream != null) {
                  try {
                      inputStream.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
          return exist;
      }
  
      /**
       * Interface responsible for receiving menu item click events if the items themselves
       * do not have individual item click listeners.
       */
      public interface OnMenuItemClickListener {
          /**
           * This method will be invoked when a menu item is clicked if the item itself did
           * not already handle the event.
           *
           * @param item {@link MenuItem} that was clicked
           * @return <code>true</code> if the event was handled, <code>false</code> otherwise.
           */
          public boolean onMenuItemClick(MenuItem item);
      }
  
      /**
       * Layout information for child views of Toolbars.
       * <p/>
       * <p>Toolbar.LayoutParams extends ActionBar.LayoutParams for compatibility with existing
       * ActionBar API. See
       * {@link android.support.v7.app.AppCompatActivity#setSupportActionBar(RtlToolbar)
       * ActionBarActivity.setActionBar}
       * for more info on how to use a Toolbar as your Activity's ActionBar.</p>
       */
      public static class LayoutParams extends ActionBar.LayoutParams {
          static final int CUSTOM = 0;
          static final int SYSTEM = 1;
          static final int EXPANDED = 2;
  
          int mViewType = CUSTOM;
  
          public LayoutParams(@NonNull Context c, AttributeSet attrs) {
              super(c, attrs);
          }
  
          public LayoutParams(int width, int height) {
              super(width, height);
              this.gravity = Gravity.CENTER_VERTICAL | GravityCompat.START;
          }
  
          public LayoutParams(int width, int height, int gravity) {
              super(width, height);
              this.gravity = gravity;
          }
  
          public LayoutParams(int gravity) {
              this(WRAP_CONTENT, MATCH_PARENT, gravity);
          }
  
          public LayoutParams(LayoutParams source) {
              super(source);
  
              mViewType = source.mViewType;
          }
  
          public LayoutParams(ActionBar.LayoutParams source) {
              super(source);
          }
  
          public LayoutParams(MarginLayoutParams source) {
              super(source);
              // ActionBar.LayoutParams doesn't have a MarginLayoutParams constructor.
              // Fake it here and copy over the relevant data.
              copyMarginsFromCompat(source);
          }
  
          public LayoutParams(ViewGroup.LayoutParams source) {
              super(source);
          }
  
          void copyMarginsFromCompat(MarginLayoutParams source) {
              this.leftMargin = source.leftMargin;
              this.topMargin = source.topMargin;
              this.rightMargin = source.rightMargin;
              this.bottomMargin = source.bottomMargin;
          }
      }
  
      public static class SavedState extends BaseSavedState {
          int expandedMenuItemId;
          boolean isOverflowOpen;
  
          public SavedState(Parcel source) {
              super(source);
              expandedMenuItemId = source.readInt();
              isOverflowOpen = source.readInt() != 0;
          }
  
          public SavedState(Parcelable superState) {
              super(superState);
          }
  
          @Override
          public void writeToParcel(Parcel out, int flags) {
              super.writeToParcel(out, flags);
              out.writeInt(expandedMenuItemId);
              out.writeInt(isOverflowOpen ? 1 : 0);
          }
  
          public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
              @Override
              public SavedState createFromParcel(Parcel source) {
                  return new SavedState(source);
              }
  
              @Override
              public SavedState[] newArray(int size) {
                  return new SavedState[size];
              }
          };
      }
  
      private class ExpandedActionViewMenuPresenter implements MenuPresenter {
          MenuBuilder mMenu;
          MenuItemImpl mCurrentExpandedItem;
  
          @Override
          public void initForMenu(Context context, MenuBuilder menu) {
              // Clear the expanded action view when menus change.
              if (mMenu != null && mCurrentExpandedItem != null) {
                  mMenu.collapseItemActionView(mCurrentExpandedItem);
              }
              mMenu = menu;
          }
  
          @Override
          public MenuView getMenuView(ViewGroup root) {
              return null;
          }
  
          @Override
          public void updateMenuView(boolean cleared) {
              // Make sure the expanded item we have is still there.
              if (mCurrentExpandedItem != null) {
                  boolean found = false;
  
                  if (mMenu != null) {
                      final int count = mMenu.size();
                      for (int i = 0; i < count; i++) {
                          final MenuItem item = mMenu.getItem(i);
                          if (item == mCurrentExpandedItem) {
                              found = true;
                              break;
                          }
                      }
                  }
  
                  if (!found) {
                      // The item we had expanded disappeared. Collapse.
                      collapseItemActionView(mMenu, mCurrentExpandedItem);
                  }
              }
          }
  
          @Override
          public void setCallback(Callback cb) {
          }
  
          @Override
          public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
              return false;
          }
  
          @Override
          public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
          }
  
          @Override
          public boolean flagActionItems() {
              return false;
          }
  
          @Override
          public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
              ensureCollapseButtonView();
              if (mCollapseButtonView.getParent() != RtlToolbar.this) {
                  addView(mCollapseButtonView);
              }
              mExpandedActionView = item.getActionView();
              mCurrentExpandedItem = item;
              if (mExpandedActionView.getParent() != RtlToolbar.this) {
                  final LayoutParams lp = generateDefaultLayoutParams();
                  lp.gravity = GravityCompat.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
                  lp.mViewType = LayoutParams.EXPANDED;
                  mExpandedActionView.setLayoutParams(lp);
                  addView(mExpandedActionView);
              }
  
              removeChildrenForExpandedActionView();
              requestLayout();
              item.setActionViewExpanded(true);
  
              if (mExpandedActionView instanceof CollapsibleActionView) {
                  ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
              }
  
              return true;
          }
  
          @Override
          public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
              // Do this before detaching the actionview from the hierarchy, in case
              // it needs to dismiss the soft keyboard, etc.
              if (mExpandedActionView instanceof CollapsibleActionView) {
                  ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
              }
  
              removeView(mExpandedActionView);
              removeView(mCollapseButtonView);
              mExpandedActionView = null;
  
              addChildrenForExpandedActionView();
              mCurrentExpandedItem = null;
              requestLayout();
              item.setActionViewExpanded(false);
  
              return true;
          }
  
          @Override
          public int getId() {
              return 0;
          }
  
          @Override
          public Parcelable onSaveInstanceState() {
              return null;
          }
  
          @Override
          public void onRestoreInstanceState(Parcelable state) {
          }
      }
  }
  