Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 
     18 package com.android.internal.widget;
     19 
     20 import android.animation.Animator;
     21 import android.animation.AnimatorListenerAdapter;
     22 import android.animation.ObjectAnimator;
     23 import android.app.ActionBar;
     24 import android.content.Context;
     25 import android.content.res.TypedArray;
     26 import android.graphics.drawable.Drawable;
     27 import android.os.Parcelable;
     28 import android.text.TextUtils;
     29 import android.util.Log;
     30 import android.util.SparseArray;
     31 import android.view.Gravity;
     32 import android.view.LayoutInflater;
     33 import android.view.Menu;
     34 import android.view.View;
     35 import android.view.ViewGroup;
     36 import android.view.Window;
     37 import android.widget.ActionMenuPresenter;
     38 import android.widget.AdapterView;
     39 import android.widget.Spinner;
     40 import android.widget.SpinnerAdapter;
     41 import android.widget.Toolbar;
     42 import com.android.internal.R;
     43 import com.android.internal.view.menu.ActionMenuItem;
     44 import com.android.internal.view.menu.MenuBuilder;
     45 import com.android.internal.view.menu.MenuPresenter;
     46 
     47 /**
     48  * Internal class used to interact with the Toolbar widget without
     49  * exposing interface methods to the public API.
     50  *
     51  * <p>ToolbarWidgetWrapper manages the differences between Toolbar and ActionBarView
     52  * so that either variant acting as a
     53  * {@link com.android.internal.app.WindowDecorActionBar WindowDecorActionBar} can behave
     54  * in the same way.</p>
     55  *
     56  * @hide
     57  */
     58 public class ToolbarWidgetWrapper implements DecorToolbar {
     59     private static final String TAG = "ToolbarWidgetWrapper";
     60 
     61     private static final int AFFECTS_LOGO_MASK =
     62             ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO;
     63     // Default fade duration for fading in/out tool bar.
     64     private static final long DEFAULT_FADE_DURATION_MS = 200;
     65 
     66     private Toolbar mToolbar;
     67 
     68     private int mDisplayOpts;
     69     private View mTabView;
     70     private Spinner mSpinner;
     71     private View mCustomView;
     72 
     73     private Drawable mIcon;
     74     private Drawable mLogo;
     75     private Drawable mNavIcon;
     76 
     77     private boolean mTitleSet;
     78     private CharSequence mTitle;
     79     private CharSequence mSubtitle;
     80     private CharSequence mHomeDescription;
     81 
     82     private Window.Callback mWindowCallback;
     83     private boolean mMenuPrepared;
     84     private ActionMenuPresenter mActionMenuPresenter;
     85 
     86     private int mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
     87     private int mDefaultNavigationContentDescription = 0;
     88     private Drawable mDefaultNavigationIcon;
     89 
     90     public ToolbarWidgetWrapper(Toolbar toolbar, boolean style) {
     91         this(toolbar, style, R.string.action_bar_up_description);
     92     }
     93 
     94     public ToolbarWidgetWrapper(Toolbar toolbar, boolean style,
     95             int defaultNavigationContentDescription) {
     96         mToolbar = toolbar;
     97 
     98         mTitle = toolbar.getTitle();
     99         mSubtitle = toolbar.getSubtitle();
    100         mTitleSet = mTitle != null;
    101         mNavIcon = mToolbar.getNavigationIcon();
    102         final TypedArray a = toolbar.getContext().obtainStyledAttributes(null,
    103                 R.styleable.ActionBar, R.attr.actionBarStyle, 0);
    104         mDefaultNavigationIcon = a.getDrawable(R.styleable.ActionBar_homeAsUpIndicator);
    105         if (style) {
    106             final CharSequence title = a.getText(R.styleable.ActionBar_title);
    107             if (!TextUtils.isEmpty(title)) {
    108                 setTitle(title);
    109             }
    110 
    111             final CharSequence subtitle = a.getText(R.styleable.ActionBar_subtitle);
    112             if (!TextUtils.isEmpty(subtitle)) {
    113                 setSubtitle(subtitle);
    114             }
    115 
    116             final Drawable logo = a.getDrawable(R.styleable.ActionBar_logo);
    117             if (logo != null) {
    118                 setLogo(logo);
    119             }
    120 
    121             final Drawable icon = a.getDrawable(R.styleable.ActionBar_icon);
    122             if (icon != null) {
    123                 setIcon(icon);
    124             }
    125             if (mNavIcon == null && mDefaultNavigationIcon != null) {
    126                 setNavigationIcon(mDefaultNavigationIcon);
    127             }
    128             setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, 0));
    129 
    130             final int customNavId = a.getResourceId(
    131                     R.styleable.ActionBar_customNavigationLayout, 0);
    132             if (customNavId != 0) {
    133                 setCustomView(LayoutInflater.from(mToolbar.getContext()).inflate(customNavId,
    134                         mToolbar, false));
    135                 setDisplayOptions(mDisplayOpts | ActionBar.DISPLAY_SHOW_CUSTOM);
    136             }
    137 
    138             final int height = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
    139             if (height > 0) {
    140                 final ViewGroup.LayoutParams lp = mToolbar.getLayoutParams();
    141                 lp.height = height;
    142                 mToolbar.setLayoutParams(lp);
    143             }
    144 
    145             final int contentInsetStart = a.getDimensionPixelOffset(
    146                     R.styleable.ActionBar_contentInsetStart, -1);
    147             final int contentInsetEnd = a.getDimensionPixelOffset(
    148                     R.styleable.ActionBar_contentInsetEnd, -1);
    149             if (contentInsetStart >= 0 || contentInsetEnd >= 0) {
    150                 mToolbar.setContentInsetsRelative(Math.max(contentInsetStart, 0),
    151                         Math.max(contentInsetEnd, 0));
    152             }
    153 
    154             final int titleTextStyle = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0);
    155             if (titleTextStyle != 0) {
    156                 mToolbar.setTitleTextAppearance(mToolbar.getContext(), titleTextStyle);
    157             }
    158 
    159             final int subtitleTextStyle = a.getResourceId(
    160                     R.styleable.ActionBar_subtitleTextStyle, 0);
    161             if (subtitleTextStyle != 0) {
    162                 mToolbar.setSubtitleTextAppearance(mToolbar.getContext(), subtitleTextStyle);
    163             }
    164 
    165             final int popupTheme = a.getResourceId(R.styleable.ActionBar_popupTheme, 0);
    166             if (popupTheme != 0) {
    167                 mToolbar.setPopupTheme(popupTheme);
    168             }
    169         } else {
    170             mDisplayOpts = detectDisplayOptions();
    171         }
    172         a.recycle();
    173 
    174         setDefaultNavigationContentDescription(defaultNavigationContentDescription);
    175         mHomeDescription = mToolbar.getNavigationContentDescription();
    176 
    177         mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
    178             final ActionMenuItem mNavItem = new ActionMenuItem(mToolbar.getContext(),
    179                     0, android.R.id.home, 0, 0, mTitle);
    180             @Override
    181             public void onClick(View v) {
    182                 if (mWindowCallback != null && mMenuPrepared) {
    183                     mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mNavItem);
    184                 }
    185             }
    186         });
    187     }
    188 
    189     @Override
    190     public void setDefaultNavigationContentDescription(int defaultNavigationContentDescription) {
    191         if (defaultNavigationContentDescription == mDefaultNavigationContentDescription) {
    192             return;
    193         }
    194         mDefaultNavigationContentDescription = defaultNavigationContentDescription;
    195         if (TextUtils.isEmpty(mToolbar.getNavigationContentDescription())) {
    196             setNavigationContentDescription(mDefaultNavigationContentDescription);
    197         }
    198     }
    199 
    200     private int detectDisplayOptions() {
    201         int opts = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME |
    202                 ActionBar.DISPLAY_USE_LOGO;
    203         if (mToolbar.getNavigationIcon() != null) {
    204             opts |= ActionBar.DISPLAY_HOME_AS_UP;
    205             mDefaultNavigationIcon = mToolbar.getNavigationIcon();
    206         }
    207         return opts;
    208     }
    209 
    210     @Override
    211     public ViewGroup getViewGroup() {
    212         return mToolbar;
    213     }
    214 
    215     @Override
    216     public Context getContext() {
    217         return mToolbar.getContext();
    218     }
    219 
    220     @Override
    221     public boolean isSplit() {
    222         return false;
    223     }
    224 
    225     @Override
    226     public boolean hasExpandedActionView() {
    227         return mToolbar.hasExpandedActionView();
    228     }
    229 
    230     @Override
    231     public void collapseActionView() {
    232         mToolbar.collapseActionView();
    233     }
    234 
    235     @Override
    236     public void setWindowCallback(Window.Callback cb) {
    237         mWindowCallback = cb;
    238     }
    239 
    240     @Override
    241     public void setWindowTitle(CharSequence title) {
    242         // "Real" title always trumps window title.
    243         if (!mTitleSet) {
    244             setTitleInt(title);
    245         }
    246     }
    247 
    248     @Override
    249     public CharSequence getTitle() {
    250         return mToolbar.getTitle();
    251     }
    252 
    253     @Override
    254     public void setTitle(CharSequence title) {
    255         mTitleSet = true;
    256         setTitleInt(title);
    257     }
    258 
    259     private void setTitleInt(CharSequence title) {
    260         mTitle = title;
    261         if ((mDisplayOpts & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
    262             mToolbar.setTitle(title);
    263         }
    264     }
    265 
    266     @Override
    267     public CharSequence getSubtitle() {
    268         return mToolbar.getSubtitle();
    269     }
    270 
    271     @Override
    272     public void setSubtitle(CharSequence subtitle) {
    273         mSubtitle = subtitle;
    274         if ((mDisplayOpts & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
    275             mToolbar.setSubtitle(subtitle);
    276         }
    277     }
    278 
    279     @Override
    280     public void initProgress() {
    281         Log.i(TAG, "Progress display unsupported");
    282     }
    283 
    284     @Override
    285     public void initIndeterminateProgress() {
    286         Log.i(TAG, "Progress display unsupported");
    287     }
    288 
    289     @Override
    290     public boolean canSplit() {
    291         return false;
    292     }
    293 
    294     @Override
    295     public void setSplitView(ViewGroup splitView) {
    296     }
    297 
    298     @Override
    299     public void setSplitToolbar(boolean split) {
    300         if (split) {
    301             throw new UnsupportedOperationException("Cannot split an android.widget.Toolbar");
    302         }
    303     }
    304 
    305     @Override
    306     public void setSplitWhenNarrow(boolean splitWhenNarrow) {
    307         // Ignore.
    308     }
    309 
    310     @Override
    311     public boolean hasIcon() {
    312         return mIcon != null;
    313     }
    314 
    315     @Override
    316     public boolean hasLogo() {
    317         return mLogo != null;
    318     }
    319 
    320     @Override
    321     public void setIcon(int resId) {
    322         setIcon(resId != 0 ? getContext().getDrawable(resId) : null);
    323     }
    324 
    325     @Override
    326     public void setIcon(Drawable d) {
    327         mIcon = d;
    328         updateToolbarLogo();
    329     }
    330 
    331     @Override
    332     public void setLogo(int resId) {
    333         setLogo(resId != 0 ? getContext().getDrawable(resId) : null);
    334     }
    335 
    336     @Override
    337     public void setLogo(Drawable d) {
    338         mLogo = d;
    339         updateToolbarLogo();
    340     }
    341 
    342     private void updateToolbarLogo() {
    343         Drawable logo = null;
    344         if ((mDisplayOpts & ActionBar.DISPLAY_SHOW_HOME) != 0) {
    345             if ((mDisplayOpts & ActionBar.DISPLAY_USE_LOGO) != 0) {
    346                 logo = mLogo != null ? mLogo : mIcon;
    347             } else {
    348                 logo = mIcon;
    349             }
    350         }
    351         mToolbar.setLogo(logo);
    352     }
    353 
    354     @Override
    355     public boolean canShowOverflowMenu() {
    356         return mToolbar.canShowOverflowMenu();
    357     }
    358 
    359     @Override
    360     public boolean isOverflowMenuShowing() {
    361         return mToolbar.isOverflowMenuShowing();
    362     }
    363 
    364     @Override
    365     public boolean isOverflowMenuShowPending() {
    366         return mToolbar.isOverflowMenuShowPending();
    367     }
    368 
    369     @Override
    370     public boolean showOverflowMenu() {
    371         return mToolbar.showOverflowMenu();
    372     }
    373 
    374     @Override
    375     public boolean hideOverflowMenu() {
    376         return mToolbar.hideOverflowMenu();
    377     }
    378 
    379     @Override
    380     public void setMenuPrepared() {
    381         mMenuPrepared = true;
    382     }
    383 
    384     @Override
    385     public void setMenu(Menu menu, MenuPresenter.Callback cb) {
    386         if (mActionMenuPresenter == null) {
    387             mActionMenuPresenter = new ActionMenuPresenter(mToolbar.getContext());
    388             mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter);
    389         }
    390         mActionMenuPresenter.setCallback(cb);
    391         mToolbar.setMenu((MenuBuilder) menu, mActionMenuPresenter);
    392     }
    393 
    394     @Override
    395     public void dismissPopupMenus() {
    396         mToolbar.dismissPopupMenus();
    397     }
    398 
    399     @Override
    400     public int getDisplayOptions() {
    401         return mDisplayOpts;
    402     }
    403 
    404     @Override
    405     public void setDisplayOptions(int newOpts) {
    406         final int oldOpts = mDisplayOpts;
    407         final int changed = oldOpts ^ newOpts;
    408         mDisplayOpts = newOpts;
    409         if (changed != 0) {
    410             if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
    411                 if ((newOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
    412                     updateHomeAccessibility();
    413                 }
    414                 updateNavigationIcon();
    415             }
    416 
    417             if ((changed & AFFECTS_LOGO_MASK) != 0) {
    418                 updateToolbarLogo();
    419             }
    420 
    421             if ((changed & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
    422                 if ((newOpts & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
    423                     mToolbar.setTitle(mTitle);
    424                     mToolbar.setSubtitle(mSubtitle);
    425                 } else {
    426                     mToolbar.setTitle(null);
    427                     mToolbar.setSubtitle(null);
    428                 }
    429             }
    430 
    431             if ((changed & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomView != null) {
    432                 if ((newOpts & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
    433                     mToolbar.addView(mCustomView);
    434                 } else {
    435                     mToolbar.removeView(mCustomView);
    436                 }
    437             }
    438         }
    439     }
    440 
    441     @Override
    442     public void setEmbeddedTabView(ScrollingTabContainerView tabView) {
    443         if (mTabView != null && mTabView.getParent() == mToolbar) {
    444             mToolbar.removeView(mTabView);
    445         }
    446         mTabView = tabView;
    447         if (tabView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) {
    448             mToolbar.addView(mTabView, 0);
    449             Toolbar.LayoutParams lp = (Toolbar.LayoutParams) mTabView.getLayoutParams();
    450             lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
    451             lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    452             lp.gravity = Gravity.START | Gravity.BOTTOM;
    453             tabView.setAllowCollapse(true);
    454         }
    455     }
    456 
    457     @Override
    458     public boolean hasEmbeddedTabs() {
    459         return mTabView != null;
    460     }
    461 
    462     @Override
    463     public boolean isTitleTruncated() {
    464         return mToolbar.isTitleTruncated();
    465     }
    466 
    467     @Override
    468     public void setCollapsible(boolean collapsible) {
    469         mToolbar.setCollapsible(collapsible);
    470     }
    471 
    472     @Override
    473     public void setHomeButtonEnabled(boolean enable) {
    474         // Ignore
    475     }
    476 
    477     @Override
    478     public int getNavigationMode() {
    479         return mNavigationMode;
    480     }
    481 
    482     @Override
    483     public void setNavigationMode(int mode) {
    484         final int oldMode = mNavigationMode;
    485         if (mode != oldMode) {
    486             switch (oldMode) {
    487                 case ActionBar.NAVIGATION_MODE_LIST:
    488                     if (mSpinner != null && mSpinner.getParent() == mToolbar) {
    489                         mToolbar.removeView(mSpinner);
    490                     }
    491                     break;
    492                 case ActionBar.NAVIGATION_MODE_TABS:
    493                     if (mTabView != null && mTabView.getParent() == mToolbar) {
    494                         mToolbar.removeView(mTabView);
    495                     }
    496                     break;
    497             }
    498 
    499             mNavigationMode = mode;
    500 
    501             switch (mode) {
    502                 case ActionBar.NAVIGATION_MODE_STANDARD:
    503                     break;
    504                 case ActionBar.NAVIGATION_MODE_LIST:
    505                     ensureSpinner();
    506                     mToolbar.addView(mSpinner, 0);
    507                     break;
    508                 case ActionBar.NAVIGATION_MODE_TABS:
    509                     if (mTabView != null) {
    510                         mToolbar.addView(mTabView, 0);
    511                         Toolbar.LayoutParams lp = (Toolbar.LayoutParams) mTabView.getLayoutParams();
    512                         lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
    513                         lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
    514                         lp.gravity = Gravity.START | Gravity.BOTTOM;
    515                     }
    516                     break;
    517                 default:
    518                     throw new IllegalArgumentException("Invalid navigation mode " + mode);
    519             }
    520         }
    521     }
    522 
    523     private void ensureSpinner() {
    524         if (mSpinner == null) {
    525             mSpinner = new Spinner(getContext(), null, R.attr.actionDropDownStyle);
    526             Toolbar.LayoutParams lp = new Toolbar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
    527                     ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
    528             mSpinner.setLayoutParams(lp);
    529         }
    530     }
    531 
    532     @Override
    533     public void setDropdownParams(SpinnerAdapter adapter,
    534             AdapterView.OnItemSelectedListener listener) {
    535         ensureSpinner();
    536         mSpinner.setAdapter(adapter);
    537         mSpinner.setOnItemSelectedListener(listener);
    538     }
    539 
    540     @Override
    541     public void setDropdownSelectedPosition(int position) {
    542         if (mSpinner == null) {
    543             throw new IllegalStateException(
    544                     "Can't set dropdown selected position without an adapter");
    545         }
    546         mSpinner.setSelection(position);
    547     }
    548 
    549     @Override
    550     public int getDropdownSelectedPosition() {
    551         return mSpinner != null ? mSpinner.getSelectedItemPosition() : 0;
    552     }
    553 
    554     @Override
    555     public int getDropdownItemCount() {
    556         return mSpinner != null ? mSpinner.getCount() : 0;
    557     }
    558 
    559     @Override
    560     public void setCustomView(View view) {
    561         if (mCustomView != null && (mDisplayOpts & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
    562             mToolbar.removeView(mCustomView);
    563         }
    564         mCustomView = view;
    565         if (view != null && (mDisplayOpts & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
    566             mToolbar.addView(mCustomView);
    567         }
    568     }
    569 
    570     @Override
    571     public View getCustomView() {
    572         return mCustomView;
    573     }
    574 
    575     @Override
    576     public void animateToVisibility(int visibility) {
    577         Animator anim = setupAnimatorToVisibility(visibility, DEFAULT_FADE_DURATION_MS);
    578         if (anim != null) {
    579             anim.start();
    580         }
    581     }
    582 
    583     @Override
    584     public Animator setupAnimatorToVisibility(int visibility, long duration) {
    585 
    586         if (visibility == View.GONE) {
    587             ObjectAnimator anim = ObjectAnimator.ofFloat(mToolbar, View.ALPHA, 1, 0);
    588             anim.setDuration(duration);
    589             anim.addListener(new AnimatorListenerAdapter() {
    590                         private boolean mCanceled = false;
    591                         @Override
    592                         public void onAnimationEnd(Animator animation) {
    593                             if (!mCanceled) {
    594                                 mToolbar.setVisibility(View.GONE);
    595                             }
    596                         }
    597 
    598                         @Override
    599                         public void onAnimationCancel(Animator animation) {
    600                             mCanceled = true;
    601                         }
    602                     });
    603             return anim;
    604         } else if (visibility == View.VISIBLE) {
    605             ObjectAnimator anim = ObjectAnimator.ofFloat(mToolbar, View.ALPHA, 0, 1);
    606             anim.setDuration(duration);
    607             anim.addListener(new AnimatorListenerAdapter() {
    608                         @Override
    609                         public void onAnimationStart(Animator animation) {
    610                             mToolbar.setVisibility(View.VISIBLE);
    611                         }
    612                     });
    613             return anim;
    614         }
    615         return null;
    616     }
    617 
    618     @Override
    619     public void setNavigationIcon(Drawable icon) {
    620         mNavIcon = icon;
    621         updateNavigationIcon();
    622     }
    623 
    624     @Override
    625     public void setNavigationIcon(int resId) {
    626         setNavigationIcon(resId != 0 ? mToolbar.getContext().getDrawable(resId) : null);
    627     }
    628 
    629     @Override
    630     public void setDefaultNavigationIcon(Drawable defaultNavigationIcon) {
    631         if (mDefaultNavigationIcon != defaultNavigationIcon) {
    632             mDefaultNavigationIcon = defaultNavigationIcon;
    633             updateNavigationIcon();
    634         }
    635     }
    636 
    637     private void updateNavigationIcon() {
    638         if ((mDisplayOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
    639             mToolbar.setNavigationIcon(mNavIcon != null ? mNavIcon : mDefaultNavigationIcon);
    640         } else {
    641             mToolbar.setNavigationIcon(null);
    642         }
    643     }
    644 
    645     @Override
    646     public void setNavigationContentDescription(CharSequence description) {
    647         mHomeDescription = description;
    648         updateHomeAccessibility();
    649     }
    650 
    651     @Override
    652     public void setNavigationContentDescription(int resId) {
    653         setNavigationContentDescription(resId == 0 ? null : getContext().getString(resId));
    654     }
    655 
    656     private void updateHomeAccessibility() {
    657         if ((mDisplayOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
    658             if (TextUtils.isEmpty(mHomeDescription)) {
    659                 mToolbar.setNavigationContentDescription(mDefaultNavigationContentDescription);
    660             } else {
    661                 mToolbar.setNavigationContentDescription(mHomeDescription);
    662             }
    663         }
    664     }
    665 
    666     @Override
    667     public void saveHierarchyState(SparseArray<Parcelable> toolbarStates) {
    668         mToolbar.saveHierarchyState(toolbarStates);
    669     }
    670 
    671     @Override
    672     public void restoreHierarchyState(SparseArray<Parcelable> toolbarStates) {
    673         mToolbar.restoreHierarchyState(toolbarStates);
    674     }
    675 
    676     @Override
    677     public void setBackgroundDrawable(Drawable d) {
    678         //noinspection deprecation
    679         mToolbar.setBackgroundDrawable(d);
    680     }
    681 
    682     @Override
    683     public int getHeight() {
    684         return mToolbar.getHeight();
    685     }
    686 
    687     @Override
    688     public void setVisibility(int visible) {
    689         mToolbar.setVisibility(visible);
    690     }
    691 
    692     @Override
    693     public int getVisibility() {
    694         return mToolbar.getVisibility();
    695     }
    696 
    697     @Override
    698     public void setMenuCallbacks(MenuPresenter.Callback presenterCallback,
    699             MenuBuilder.Callback menuBuilderCallback) {
    700         mToolbar.setMenuCallbacks(presenterCallback, menuBuilderCallback);
    701     }
    702 
    703     @Override
    704     public Menu getMenu() {
    705         return mToolbar.getMenu();
    706     }
    707 
    708 }
    709