Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2010 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 package com.android.internal.widget;
     18 
     19 import android.animation.LayoutTransition;
     20 import android.app.ActionBar;
     21 import android.content.Context;
     22 import android.content.res.Configuration;
     23 import android.content.res.TypedArray;
     24 import android.graphics.drawable.Drawable;
     25 import android.os.Parcel;
     26 import android.os.Parcelable;
     27 import android.text.Layout;
     28 import android.text.TextUtils;
     29 import android.util.AttributeSet;
     30 import android.view.CollapsibleActionView;
     31 import android.view.Gravity;
     32 import android.view.LayoutInflater;
     33 import android.view.Menu;
     34 import android.view.MenuItem;
     35 import android.view.MotionEvent;
     36 import android.view.View;
     37 import android.view.ViewGroup;
     38 import android.view.ViewParent;
     39 import android.view.Window;
     40 import android.view.accessibility.AccessibilityEvent;
     41 import android.widget.ActionMenuPresenter;
     42 import android.widget.ActionMenuView;
     43 import android.widget.AdapterView;
     44 import android.widget.FrameLayout;
     45 import android.widget.ImageView;
     46 import android.widget.LinearLayout;
     47 import android.widget.ProgressBar;
     48 import android.widget.Spinner;
     49 import android.widget.SpinnerAdapter;
     50 import android.widget.TextView;
     51 import com.android.internal.R;
     52 import com.android.internal.transition.ActionBarTransition;
     53 import com.android.internal.view.menu.ActionMenuItem;
     54 import com.android.internal.view.menu.MenuBuilder;
     55 import com.android.internal.view.menu.MenuItemImpl;
     56 import com.android.internal.view.menu.MenuPresenter;
     57 import com.android.internal.view.menu.MenuView;
     58 import com.android.internal.view.menu.SubMenuBuilder;
     59 
     60 /**
     61  * @hide
     62  */
     63 public class ActionBarView extends AbsActionBarView implements DecorToolbar {
     64     private static final String TAG = "ActionBarView";
     65 
     66     /**
     67      * Display options applied by default
     68      */
     69     public static final int DISPLAY_DEFAULT = 0;
     70 
     71     /**
     72      * Display options that require re-layout as opposed to a simple invalidate
     73      */
     74     private static final int DISPLAY_RELAYOUT_MASK =
     75             ActionBar.DISPLAY_SHOW_HOME |
     76             ActionBar.DISPLAY_USE_LOGO |
     77             ActionBar.DISPLAY_HOME_AS_UP |
     78             ActionBar.DISPLAY_SHOW_CUSTOM |
     79             ActionBar.DISPLAY_SHOW_TITLE |
     80             ActionBar.DISPLAY_TITLE_MULTIPLE_LINES;
     81 
     82     private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.START | Gravity.CENTER_VERTICAL;
     83 
     84     private int mNavigationMode;
     85     private int mDisplayOptions = -1;
     86     private CharSequence mTitle;
     87     private CharSequence mSubtitle;
     88     private Drawable mIcon;
     89     private Drawable mLogo;
     90     private CharSequence mHomeDescription;
     91     private int mHomeDescriptionRes;
     92 
     93     private HomeView mHomeLayout;
     94     private HomeView mExpandedHomeLayout;
     95     private LinearLayout mTitleLayout;
     96     private TextView mTitleView;
     97     private TextView mSubtitleView;
     98     private ViewGroup mUpGoerFive;
     99 
    100     private Spinner mSpinner;
    101     private LinearLayout mListNavLayout;
    102     private ScrollingTabContainerView mTabScrollView;
    103     private View mCustomNavView;
    104     private ProgressBar mProgressView;
    105     private ProgressBar mIndeterminateProgressView;
    106 
    107     private int mProgressBarPadding;
    108     private int mItemPadding;
    109 
    110     private final int mTitleStyleRes;
    111     private final int mSubtitleStyleRes;
    112     private final int mProgressStyle;
    113     private final int mIndeterminateProgressStyle;
    114 
    115     private boolean mUserTitle;
    116     private boolean mIncludeTabs;
    117     private boolean mIsCollapsible;
    118     private boolean mWasHomeEnabled; // Was it enabled before action view expansion?
    119 
    120     private MenuBuilder mOptionsMenu;
    121     private boolean mMenuPrepared;
    122 
    123     private ActionBarContextView mContextView;
    124 
    125     private ActionMenuItem mLogoNavItem;
    126 
    127     private SpinnerAdapter mSpinnerAdapter;
    128     private AdapterView.OnItemSelectedListener mNavItemSelectedListener;
    129 
    130     private Runnable mTabSelector;
    131 
    132     private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
    133     View mExpandedActionView;
    134     private int mDefaultUpDescription = R.string.action_bar_up_description;
    135 
    136     Window.Callback mWindowCallback;
    137 
    138     private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() {
    139         @Override
    140         public void onClick(View v) {
    141             final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem;
    142             if (item != null) {
    143                 item.collapseActionView();
    144             }
    145         }
    146     };
    147 
    148     private final OnClickListener mUpClickListener = new OnClickListener() {
    149         public void onClick(View v) {
    150             if (mMenuPrepared) {
    151                 // Only invoke the window callback if the options menu has been initialized.
    152                 mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem);
    153             }
    154         }
    155     };
    156 
    157     public ActionBarView(Context context, AttributeSet attrs) {
    158         super(context, attrs);
    159 
    160         // Background is always provided by the container.
    161         setBackgroundResource(0);
    162 
    163         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar,
    164                 com.android.internal.R.attr.actionBarStyle, 0);
    165 
    166         mNavigationMode = a.getInt(R.styleable.ActionBar_navigationMode,
    167                 ActionBar.NAVIGATION_MODE_STANDARD);
    168         mTitle = a.getText(R.styleable.ActionBar_title);
    169         mSubtitle = a.getText(R.styleable.ActionBar_subtitle);
    170         mLogo = a.getDrawable(R.styleable.ActionBar_logo);
    171         mIcon = a.getDrawable(R.styleable.ActionBar_icon);
    172 
    173         final LayoutInflater inflater = LayoutInflater.from(context);
    174 
    175         final int homeResId = a.getResourceId(
    176                 com.android.internal.R.styleable.ActionBar_homeLayout,
    177                 com.android.internal.R.layout.action_bar_home);
    178 
    179         mUpGoerFive = (ViewGroup) inflater.inflate(
    180                 com.android.internal.R.layout.action_bar_up_container, this, false);
    181         mHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
    182 
    183         mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
    184         mExpandedHomeLayout.setShowUp(true);
    185         mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener);
    186         mExpandedHomeLayout.setContentDescription(getResources().getText(
    187                 mDefaultUpDescription));
    188 
    189         // This needs to highlight/be focusable on its own.
    190         // TODO: Clean up the handoff between expanded/normal.
    191         final Drawable upBackground = mUpGoerFive.getBackground();
    192         if (upBackground != null) {
    193             mExpandedHomeLayout.setBackground(upBackground.getConstantState().newDrawable());
    194         }
    195         mExpandedHomeLayout.setEnabled(true);
    196         mExpandedHomeLayout.setFocusable(true);
    197 
    198         mTitleStyleRes = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0);
    199         mSubtitleStyleRes = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0);
    200         mProgressStyle = a.getResourceId(R.styleable.ActionBar_progressBarStyle, 0);
    201         mIndeterminateProgressStyle = a.getResourceId(
    202                 R.styleable.ActionBar_indeterminateProgressStyle, 0);
    203 
    204         mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_progressBarPadding, 0);
    205         mItemPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_itemPadding, 0);
    206 
    207         setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT));
    208 
    209         final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
    210         if (customNavId != 0) {
    211             mCustomNavView = (View) inflater.inflate(customNavId, this, false);
    212             mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
    213             setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM);
    214         }
    215 
    216         mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
    217 
    218         a.recycle();
    219 
    220         mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle);
    221 
    222         mUpGoerFive.setOnClickListener(mUpClickListener);
    223         mUpGoerFive.setClickable(true);
    224         mUpGoerFive.setFocusable(true);
    225 
    226         if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
    227             setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
    228         }
    229     }
    230 
    231     @Override
    232     protected void onConfigurationChanged(Configuration newConfig) {
    233         super.onConfigurationChanged(newConfig);
    234 
    235         mTitleView = null;
    236         mSubtitleView = null;
    237         if (mTitleLayout != null && mTitleLayout.getParent() == mUpGoerFive) {
    238             mUpGoerFive.removeView(mTitleLayout);
    239         }
    240         mTitleLayout = null;
    241         if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
    242             initTitle();
    243         }
    244 
    245         if (mHomeDescriptionRes != 0) {
    246             setNavigationContentDescription(mHomeDescriptionRes);
    247         }
    248 
    249         if (mTabScrollView != null && mIncludeTabs) {
    250             ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams();
    251             if (lp != null) {
    252                 lp.width = LayoutParams.WRAP_CONTENT;
    253                 lp.height = LayoutParams.MATCH_PARENT;
    254             }
    255             mTabScrollView.setAllowCollapse(true);
    256         }
    257     }
    258 
    259     /**
    260      * Set the window callback used to invoke menu items; used for dispatching home button presses.
    261      * @param cb Window callback to dispatch to
    262      */
    263     public void setWindowCallback(Window.Callback cb) {
    264         mWindowCallback = cb;
    265     }
    266 
    267     @Override
    268     public void onDetachedFromWindow() {
    269         super.onDetachedFromWindow();
    270         removeCallbacks(mTabSelector);
    271         if (mActionMenuPresenter != null) {
    272             mActionMenuPresenter.hideOverflowMenu();
    273             mActionMenuPresenter.hideSubMenus();
    274         }
    275     }
    276 
    277     @Override
    278     public boolean shouldDelayChildPressedState() {
    279         return false;
    280     }
    281 
    282     public void initProgress() {
    283         mProgressView = new ProgressBar(mContext, null, 0, mProgressStyle);
    284         mProgressView.setId(R.id.progress_horizontal);
    285         mProgressView.setMax(10000);
    286         mProgressView.setVisibility(GONE);
    287         addView(mProgressView);
    288     }
    289 
    290     public void initIndeterminateProgress() {
    291         mIndeterminateProgressView = new ProgressBar(mContext, null, 0,
    292                 mIndeterminateProgressStyle);
    293         mIndeterminateProgressView.setId(R.id.progress_circular);
    294         mIndeterminateProgressView.setVisibility(GONE);
    295         addView(mIndeterminateProgressView);
    296     }
    297 
    298     @Override
    299     public void setSplitToolbar(boolean splitActionBar) {
    300         if (mSplitActionBar != splitActionBar) {
    301             if (mMenuView != null) {
    302                 final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
    303                 if (oldParent != null) {
    304                     oldParent.removeView(mMenuView);
    305                 }
    306                 if (splitActionBar) {
    307                     if (mSplitView != null) {
    308                         mSplitView.addView(mMenuView);
    309                     }
    310                     mMenuView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
    311                 } else {
    312                     addView(mMenuView);
    313                     mMenuView.getLayoutParams().width = LayoutParams.WRAP_CONTENT;
    314                 }
    315                 mMenuView.requestLayout();
    316             }
    317             if (mSplitView != null) {
    318                 mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE);
    319             }
    320 
    321             if (mActionMenuPresenter != null) {
    322                 if (!splitActionBar) {
    323                     mActionMenuPresenter.setExpandedActionViewsExclusive(
    324                             getResources().getBoolean(
    325                                     com.android.internal.R.bool.action_bar_expanded_action_views_exclusive));
    326                 } else {
    327                     mActionMenuPresenter.setExpandedActionViewsExclusive(false);
    328                     // Allow full screen width in split mode.
    329                     mActionMenuPresenter.setWidthLimit(
    330                             getContext().getResources().getDisplayMetrics().widthPixels, true);
    331                     // No limit to the item count; use whatever will fit.
    332                     mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
    333                 }
    334             }
    335             super.setSplitToolbar(splitActionBar);
    336         }
    337     }
    338 
    339     public boolean isSplit() {
    340         return mSplitActionBar;
    341     }
    342 
    343     public boolean canSplit() {
    344         return true;
    345     }
    346 
    347     public boolean hasEmbeddedTabs() {
    348         return mIncludeTabs;
    349     }
    350 
    351     @Override
    352     public void setEmbeddedTabView(ScrollingTabContainerView tabs) {
    353         if (mTabScrollView != null) {
    354             removeView(mTabScrollView);
    355         }
    356         mTabScrollView = tabs;
    357         mIncludeTabs = tabs != null;
    358         if (mIncludeTabs && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) {
    359             addView(mTabScrollView);
    360             ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams();
    361             lp.width = LayoutParams.WRAP_CONTENT;
    362             lp.height = LayoutParams.MATCH_PARENT;
    363             tabs.setAllowCollapse(true);
    364         }
    365     }
    366 
    367     public void setMenuPrepared() {
    368         mMenuPrepared = true;
    369     }
    370 
    371     public void setMenu(Menu menu, MenuPresenter.Callback cb) {
    372         if (menu == mOptionsMenu) return;
    373 
    374         if (mOptionsMenu != null) {
    375             mOptionsMenu.removeMenuPresenter(mActionMenuPresenter);
    376             mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter);
    377         }
    378 
    379         MenuBuilder builder = (MenuBuilder) menu;
    380         mOptionsMenu = builder;
    381         if (mMenuView != null) {
    382             final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
    383             if (oldParent != null) {
    384                 oldParent.removeView(mMenuView);
    385             }
    386         }
    387         if (mActionMenuPresenter == null) {
    388             mActionMenuPresenter = new ActionMenuPresenter(mContext);
    389             mActionMenuPresenter.setCallback(cb);
    390             mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter);
    391             mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
    392         }
    393 
    394         ActionMenuView menuView;
    395         final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
    396                 LayoutParams.MATCH_PARENT);
    397         if (!mSplitActionBar) {
    398             mActionMenuPresenter.setExpandedActionViewsExclusive(
    399                     getResources().getBoolean(
    400                     com.android.internal.R.bool.action_bar_expanded_action_views_exclusive));
    401             configPresenters(builder);
    402             menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
    403             final ViewGroup oldParent = (ViewGroup) menuView.getParent();
    404             if (oldParent != null && oldParent != this) {
    405                 oldParent.removeView(menuView);
    406             }
    407             addView(menuView, layoutParams);
    408         } else {
    409             mActionMenuPresenter.setExpandedActionViewsExclusive(false);
    410             // Allow full screen width in split mode.
    411             mActionMenuPresenter.setWidthLimit(
    412                     getContext().getResources().getDisplayMetrics().widthPixels, true);
    413             // No limit to the item count; use whatever will fit.
    414             mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
    415             // Span the whole width
    416             layoutParams.width = LayoutParams.MATCH_PARENT;
    417             layoutParams.height = LayoutParams.WRAP_CONTENT;
    418             configPresenters(builder);
    419             menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
    420             if (mSplitView != null) {
    421                 final ViewGroup oldParent = (ViewGroup) menuView.getParent();
    422                 if (oldParent != null && oldParent != mSplitView) {
    423                     oldParent.removeView(menuView);
    424                 }
    425                 menuView.setVisibility(getAnimatedVisibility());
    426                 mSplitView.addView(menuView, layoutParams);
    427             } else {
    428                 // We'll add this later if we missed it this time.
    429                 menuView.setLayoutParams(layoutParams);
    430             }
    431         }
    432         mMenuView = menuView;
    433     }
    434 
    435     private void configPresenters(MenuBuilder builder) {
    436         if (builder != null) {
    437             builder.addMenuPresenter(mActionMenuPresenter, mPopupContext);
    438             builder.addMenuPresenter(mExpandedMenuPresenter, mPopupContext);
    439         } else {
    440             mActionMenuPresenter.initForMenu(mPopupContext, null);
    441             mExpandedMenuPresenter.initForMenu(mPopupContext, null);
    442             mActionMenuPresenter.updateMenuView(true);
    443             mExpandedMenuPresenter.updateMenuView(true);
    444         }
    445     }
    446 
    447     public boolean hasExpandedActionView() {
    448         return mExpandedMenuPresenter != null &&
    449                 mExpandedMenuPresenter.mCurrentExpandedItem != null;
    450     }
    451 
    452     public void collapseActionView() {
    453         final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
    454                 mExpandedMenuPresenter.mCurrentExpandedItem;
    455         if (item != null) {
    456             item.collapseActionView();
    457         }
    458     }
    459 
    460     public void setCustomView(View view) {
    461         final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
    462         if (showCustom) {
    463             ActionBarTransition.beginDelayedTransition(this);
    464         }
    465         if (mCustomNavView != null && showCustom) {
    466             removeView(mCustomNavView);
    467         }
    468         mCustomNavView = view;
    469         if (mCustomNavView != null && showCustom) {
    470             addView(mCustomNavView);
    471         }
    472     }
    473 
    474     public CharSequence getTitle() {
    475         return mTitle;
    476     }
    477 
    478     /**
    479      * Set the action bar title. This will always replace or override window titles.
    480      * @param title Title to set
    481      *
    482      * @see #setWindowTitle(CharSequence)
    483      */
    484     public void setTitle(CharSequence title) {
    485         mUserTitle = true;
    486         setTitleImpl(title);
    487     }
    488 
    489     /**
    490      * Set the window title. A window title will always be replaced or overridden by a user title.
    491      * @param title Title to set
    492      *
    493      * @see #setTitle(CharSequence)
    494      */
    495     public void setWindowTitle(CharSequence title) {
    496         if (!mUserTitle) {
    497             setTitleImpl(title);
    498         }
    499     }
    500 
    501     private void setTitleImpl(CharSequence title) {
    502         ActionBarTransition.beginDelayedTransition(this);
    503         mTitle = title;
    504         if (mTitleView != null) {
    505             mTitleView.setText(title);
    506             final boolean visible = mExpandedActionView == null &&
    507                     (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
    508                     (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
    509             mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
    510         }
    511         if (mLogoNavItem != null) {
    512             mLogoNavItem.setTitle(title);
    513         }
    514         updateHomeAccessibility(mUpGoerFive.isEnabled());
    515     }
    516 
    517     public CharSequence getSubtitle() {
    518         return mSubtitle;
    519     }
    520 
    521     public void setSubtitle(CharSequence subtitle) {
    522         ActionBarTransition.beginDelayedTransition(this);
    523         mSubtitle = subtitle;
    524         if (mSubtitleView != null) {
    525             mSubtitleView.setText(subtitle);
    526             mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE);
    527             final boolean visible = mExpandedActionView == null &&
    528                     (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
    529                     (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
    530             mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
    531         }
    532         updateHomeAccessibility(mUpGoerFive.isEnabled());
    533     }
    534 
    535     public void setHomeButtonEnabled(boolean enable) {
    536         setHomeButtonEnabled(enable, true);
    537     }
    538 
    539     private void setHomeButtonEnabled(boolean enable, boolean recordState) {
    540         if (recordState) {
    541             mWasHomeEnabled = enable;
    542         }
    543 
    544         if (mExpandedActionView != null) {
    545             // There's an action view currently showing and we want to keep the state
    546             // configured for the action view at the moment. If we needed to record the
    547             // new state for later we will have done so above.
    548             return;
    549         }
    550 
    551         mUpGoerFive.setEnabled(enable);
    552         mUpGoerFive.setFocusable(enable);
    553         // Make sure the home button has an accurate content description for accessibility.
    554         updateHomeAccessibility(enable);
    555     }
    556 
    557     private void updateHomeAccessibility(boolean homeEnabled) {
    558         if (!homeEnabled) {
    559             mUpGoerFive.setContentDescription(null);
    560             mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
    561         } else {
    562             mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
    563             mUpGoerFive.setContentDescription(buildHomeContentDescription());
    564         }
    565     }
    566 
    567     /**
    568      * Compose a content description for the Home/Up affordance.
    569      *
    570      * <p>As this encompasses the icon/logo, title and subtitle all in one, we need
    571      * a description for the whole wad of stuff that can be localized properly.</p>
    572      */
    573     private CharSequence buildHomeContentDescription() {
    574         final CharSequence homeDesc;
    575         if (mHomeDescription != null) {
    576             homeDesc = mHomeDescription;
    577         } else {
    578             if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
    579                 homeDesc = mContext.getResources().getText(mDefaultUpDescription);
    580             } else {
    581                 homeDesc = mContext.getResources().getText(R.string.action_bar_home_description);
    582             }
    583         }
    584 
    585         final CharSequence title = getTitle();
    586         final CharSequence subtitle = getSubtitle();
    587         if (!TextUtils.isEmpty(title)) {
    588             final String result;
    589             if (!TextUtils.isEmpty(subtitle)) {
    590                 result = getResources().getString(
    591                         R.string.action_bar_home_subtitle_description_format,
    592                         title, subtitle, homeDesc);
    593             } else {
    594                 result = getResources().getString(R.string.action_bar_home_description_format,
    595                         title, homeDesc);
    596             }
    597             return result;
    598         }
    599         return homeDesc;
    600     }
    601 
    602     public void setDisplayOptions(int options) {
    603         final int flagsChanged = mDisplayOptions == -1 ? -1 : options ^ mDisplayOptions;
    604         mDisplayOptions = options;
    605 
    606         if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) {
    607             ActionBarTransition.beginDelayedTransition(this);
    608 
    609             if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
    610                 final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0;
    611                 mHomeLayout.setShowUp(setUp);
    612 
    613                 // Showing home as up implicitly enables interaction with it.
    614                 // In honeycomb it was always enabled, so make this transition
    615                 // a bit easier for developers in the common case.
    616                 // (It would be silly to show it as up without responding to it.)
    617                 if (setUp) {
    618                     setHomeButtonEnabled(true);
    619                 }
    620             }
    621 
    622             if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) {
    623                 final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0;
    624                 mHomeLayout.setIcon(logoVis ? mLogo : mIcon);
    625             }
    626 
    627             if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
    628                 if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
    629                     initTitle();
    630                 } else {
    631                     mUpGoerFive.removeView(mTitleLayout);
    632                 }
    633             }
    634 
    635             final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0;
    636             final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
    637             final boolean titleUp = !showHome && homeAsUp;
    638             mHomeLayout.setShowIcon(showHome);
    639 
    640             final int homeVis = (showHome || titleUp) && mExpandedActionView == null ?
    641                     VISIBLE : GONE;
    642             mHomeLayout.setVisibility(homeVis);
    643 
    644             if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) {
    645                 if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
    646                     addView(mCustomNavView);
    647                 } else {
    648                     removeView(mCustomNavView);
    649                 }
    650             }
    651 
    652             if (mTitleLayout != null &&
    653                     (flagsChanged & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
    654                 if ((options & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
    655                     mTitleView.setSingleLine(false);
    656                     mTitleView.setMaxLines(2);
    657                 } else {
    658                     mTitleView.setMaxLines(1);
    659                     mTitleView.setSingleLine(true);
    660                 }
    661             }
    662 
    663             requestLayout();
    664         } else {
    665             invalidate();
    666         }
    667 
    668         // Make sure the home button has an accurate content description for accessibility.
    669         updateHomeAccessibility(mUpGoerFive.isEnabled());
    670     }
    671 
    672     public void setIcon(Drawable icon) {
    673         mIcon = icon;
    674         if (icon != null &&
    675                 ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) {
    676             mHomeLayout.setIcon(icon);
    677         }
    678         if (mExpandedActionView != null) {
    679             mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
    680         }
    681     }
    682 
    683     public void setIcon(int resId) {
    684         setIcon(resId != 0 ? mContext.getDrawable(resId) : null);
    685     }
    686 
    687     public boolean hasIcon() {
    688         return mIcon != null;
    689     }
    690 
    691     public void setLogo(Drawable logo) {
    692         mLogo = logo;
    693         if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) {
    694             mHomeLayout.setIcon(logo);
    695         }
    696     }
    697 
    698     public void setLogo(int resId) {
    699         setLogo(resId != 0 ? mContext.getDrawable(resId) : null);
    700     }
    701 
    702     public boolean hasLogo() {
    703         return mLogo != null;
    704     }
    705 
    706     public void setNavigationMode(int mode) {
    707         final int oldMode = mNavigationMode;
    708         if (mode != oldMode) {
    709             ActionBarTransition.beginDelayedTransition(this);
    710             switch (oldMode) {
    711             case ActionBar.NAVIGATION_MODE_LIST:
    712                 if (mListNavLayout != null) {
    713                     removeView(mListNavLayout);
    714                 }
    715                 break;
    716             case ActionBar.NAVIGATION_MODE_TABS:
    717                 if (mTabScrollView != null && mIncludeTabs) {
    718                     removeView(mTabScrollView);
    719                 }
    720             }
    721 
    722             switch (mode) {
    723             case ActionBar.NAVIGATION_MODE_LIST:
    724                 if (mSpinner == null) {
    725                     mSpinner = new Spinner(mContext, null,
    726                             com.android.internal.R.attr.actionDropDownStyle);
    727                     mSpinner.setId(com.android.internal.R.id.action_bar_spinner);
    728                     mListNavLayout = new LinearLayout(mContext, null,
    729                             com.android.internal.R.attr.actionBarTabBarStyle);
    730                     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
    731                             LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
    732                     params.gravity = Gravity.CENTER;
    733                     mListNavLayout.addView(mSpinner, params);
    734                 }
    735                 if (mSpinner.getAdapter() != mSpinnerAdapter) {
    736                     mSpinner.setAdapter(mSpinnerAdapter);
    737                 }
    738                 mSpinner.setOnItemSelectedListener(mNavItemSelectedListener);
    739                 addView(mListNavLayout);
    740                 break;
    741             case ActionBar.NAVIGATION_MODE_TABS:
    742                 if (mTabScrollView != null && mIncludeTabs) {
    743                     addView(mTabScrollView);
    744                 }
    745                 break;
    746             }
    747             mNavigationMode = mode;
    748             requestLayout();
    749         }
    750     }
    751 
    752     public void setDropdownParams(SpinnerAdapter adapter, AdapterView.OnItemSelectedListener l) {
    753         mSpinnerAdapter = adapter;
    754         mNavItemSelectedListener = l;
    755         if (mSpinner != null) {
    756             mSpinner.setAdapter(adapter);
    757             mSpinner.setOnItemSelectedListener(l);
    758         }
    759     }
    760 
    761     public int getDropdownItemCount() {
    762         return mSpinnerAdapter != null ? mSpinnerAdapter.getCount() : 0;
    763     }
    764 
    765     public void setDropdownSelectedPosition(int position) {
    766         mSpinner.setSelection(position);
    767     }
    768 
    769     public int getDropdownSelectedPosition() {
    770         return mSpinner.getSelectedItemPosition();
    771     }
    772 
    773     public View getCustomView() {
    774         return mCustomNavView;
    775     }
    776 
    777     public int getNavigationMode() {
    778         return mNavigationMode;
    779     }
    780 
    781     public int getDisplayOptions() {
    782         return mDisplayOptions;
    783     }
    784 
    785     @Override
    786     public ViewGroup getViewGroup() {
    787         return this;
    788     }
    789 
    790     @Override
    791     protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
    792         // Used by custom nav views if they don't supply layout params. Everything else
    793         // added to an ActionBarView should have them already.
    794         return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY);
    795     }
    796 
    797     @Override
    798     protected void onFinishInflate() {
    799         super.onFinishInflate();
    800 
    801         mUpGoerFive.addView(mHomeLayout, 0);
    802         addView(mUpGoerFive);
    803 
    804         if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
    805             final ViewParent parent = mCustomNavView.getParent();
    806             if (parent != this) {
    807                 if (parent instanceof ViewGroup) {
    808                     ((ViewGroup) parent).removeView(mCustomNavView);
    809                 }
    810                 addView(mCustomNavView);
    811             }
    812         }
    813     }
    814 
    815     private void initTitle() {
    816         if (mTitleLayout == null) {
    817             LayoutInflater inflater = LayoutInflater.from(getContext());
    818             mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item,
    819                     this, false);
    820             mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
    821             mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
    822 
    823             if (mTitleStyleRes != 0) {
    824                 mTitleView.setTextAppearance(mContext, mTitleStyleRes);
    825             }
    826             if (mTitle != null) {
    827                 mTitleView.setText(mTitle);
    828             }
    829 
    830             if (mSubtitleStyleRes != 0) {
    831                 mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes);
    832             }
    833             if (mSubtitle != null) {
    834                 mSubtitleView.setText(mSubtitle);
    835                 mSubtitleView.setVisibility(VISIBLE);
    836             }
    837         }
    838 
    839         ActionBarTransition.beginDelayedTransition(this);
    840         mUpGoerFive.addView(mTitleLayout);
    841         if (mExpandedActionView != null ||
    842                 (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) {
    843             // Don't show while in expanded mode or with empty text
    844             mTitleLayout.setVisibility(GONE);
    845         } else {
    846             mTitleLayout.setVisibility(VISIBLE);
    847         }
    848     }
    849 
    850     public void setContextView(ActionBarContextView view) {
    851         mContextView = view;
    852     }
    853 
    854     public void setCollapsible(boolean collapsible) {
    855         mIsCollapsible = collapsible;
    856     }
    857 
    858     /**
    859      * @return True if any characters in the title were truncated
    860      */
    861     public boolean isTitleTruncated() {
    862         if (mTitleView == null) {
    863             return false;
    864         }
    865 
    866         final Layout titleLayout = mTitleView.getLayout();
    867         if (titleLayout == null) {
    868             return false;
    869         }
    870 
    871         final int lineCount = titleLayout.getLineCount();
    872         for (int i = 0; i < lineCount; i++) {
    873             if (titleLayout.getEllipsisCount(i) > 0) {
    874                 return true;
    875             }
    876         }
    877         return false;
    878     }
    879 
    880     @Override
    881     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    882         final int childCount = getChildCount();
    883         if (mIsCollapsible) {
    884             int visibleChildren = 0;
    885             for (int i = 0; i < childCount; i++) {
    886                 final View child = getChildAt(i);
    887                 if (child.getVisibility() != GONE &&
    888                         !(child == mMenuView && mMenuView.getChildCount() == 0) &&
    889                         child != mUpGoerFive) {
    890                     visibleChildren++;
    891                 }
    892             }
    893 
    894             final int upChildCount = mUpGoerFive.getChildCount();
    895             for (int i = 0; i < upChildCount; i++) {
    896                 final View child = mUpGoerFive.getChildAt(i);
    897                 if (child.getVisibility() != GONE) {
    898                     visibleChildren++;
    899                 }
    900             }
    901 
    902             if (visibleChildren == 0) {
    903                 // No size for an empty action bar when collapsable.
    904                 setMeasuredDimension(0, 0);
    905                 return;
    906             }
    907         }
    908 
    909         int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    910         if (widthMode != MeasureSpec.EXACTLY) {
    911             throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
    912                     "with android:layout_width=\"match_parent\" (or fill_parent)");
    913         }
    914 
    915         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    916         if (heightMode != MeasureSpec.AT_MOST) {
    917             throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
    918                     "with android:layout_height=\"wrap_content\"");
    919         }
    920 
    921         int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
    922 
    923         int maxHeight = mContentHeight >= 0 ?
    924                 mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
    925 
    926         final int verticalPadding = getPaddingTop() + getPaddingBottom();
    927         final int paddingLeft = getPaddingLeft();
    928         final int paddingRight = getPaddingRight();
    929         final int height = maxHeight - verticalPadding;
    930         final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
    931         final int exactHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
    932 
    933         int availableWidth = contentWidth - paddingLeft - paddingRight;
    934         int leftOfCenter = availableWidth / 2;
    935         int rightOfCenter = leftOfCenter;
    936 
    937         final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
    938                 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
    939 
    940         HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
    941 
    942         final ViewGroup.LayoutParams homeLp = homeLayout.getLayoutParams();
    943         int homeWidthSpec;
    944         if (homeLp.width < 0) {
    945             homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
    946         } else {
    947             homeWidthSpec = MeasureSpec.makeMeasureSpec(homeLp.width, MeasureSpec.EXACTLY);
    948         }
    949 
    950         /*
    951          * This is a little weird.
    952          * We're only measuring the *home* affordance within the Up container here
    953          * on purpose, because we want to give the available space to all other views before
    954          * the title text. We'll remeasure the whole up container again later.
    955          * We need to measure this container so we know the right offset for the up affordance
    956          * no matter what.
    957          */
    958         homeLayout.measure(homeWidthSpec, exactHeightSpec);
    959 
    960         int homeWidth = 0;
    961         if ((homeLayout.getVisibility() != GONE && homeLayout.getParent() == mUpGoerFive)
    962                 || showTitle) {
    963             homeWidth = homeLayout.getMeasuredWidth();
    964             final int homeOffsetWidth = homeWidth + homeLayout.getStartOffset();
    965             availableWidth = Math.max(0, availableWidth - homeOffsetWidth);
    966             leftOfCenter = Math.max(0, availableWidth - homeOffsetWidth);
    967         }
    968 
    969         if (mMenuView != null && mMenuView.getParent() == this) {
    970             availableWidth = measureChildView(mMenuView, availableWidth, exactHeightSpec, 0);
    971             rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth());
    972         }
    973 
    974         if (mIndeterminateProgressView != null &&
    975                 mIndeterminateProgressView.getVisibility() != GONE) {
    976             availableWidth = measureChildView(mIndeterminateProgressView, availableWidth,
    977                     childSpecHeight, 0);
    978             rightOfCenter = Math.max(0,
    979                     rightOfCenter - mIndeterminateProgressView.getMeasuredWidth());
    980         }
    981 
    982         if (mExpandedActionView == null) {
    983             switch (mNavigationMode) {
    984                 case ActionBar.NAVIGATION_MODE_LIST:
    985                     if (mListNavLayout != null) {
    986                         final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
    987                         availableWidth = Math.max(0, availableWidth - itemPaddingSize);
    988                         leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
    989                         mListNavLayout.measure(
    990                                 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
    991                                 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
    992                         final int listNavWidth = mListNavLayout.getMeasuredWidth();
    993                         availableWidth = Math.max(0, availableWidth - listNavWidth);
    994                         leftOfCenter = Math.max(0, leftOfCenter - listNavWidth);
    995                     }
    996                     break;
    997                 case ActionBar.NAVIGATION_MODE_TABS:
    998                     if (mTabScrollView != null) {
    999                         final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
   1000                         availableWidth = Math.max(0, availableWidth - itemPaddingSize);
   1001                         leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
   1002                         mTabScrollView.measure(
   1003                                 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
   1004                                 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
   1005                         final int tabWidth = mTabScrollView.getMeasuredWidth();
   1006                         availableWidth = Math.max(0, availableWidth - tabWidth);
   1007                         leftOfCenter = Math.max(0, leftOfCenter - tabWidth);
   1008                     }
   1009                     break;
   1010             }
   1011         }
   1012 
   1013         View customView = null;
   1014         if (mExpandedActionView != null) {
   1015             customView = mExpandedActionView;
   1016         } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
   1017                 mCustomNavView != null) {
   1018             customView = mCustomNavView;
   1019         }
   1020 
   1021         if (customView != null) {
   1022             final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams());
   1023             final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
   1024                     (ActionBar.LayoutParams) lp : null;
   1025 
   1026             int horizontalMargin = 0;
   1027             int verticalMargin = 0;
   1028             if (ablp != null) {
   1029                 horizontalMargin = ablp.leftMargin + ablp.rightMargin;
   1030                 verticalMargin = ablp.topMargin + ablp.bottomMargin;
   1031             }
   1032 
   1033             // If the action bar is wrapping to its content height, don't allow a custom
   1034             // view to MATCH_PARENT.
   1035             int customNavHeightMode;
   1036             if (mContentHeight <= 0) {
   1037                 customNavHeightMode = MeasureSpec.AT_MOST;
   1038             } else {
   1039                 customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ?
   1040                         MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
   1041             }
   1042             final int customNavHeight = Math.max(0,
   1043                     (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin);
   1044 
   1045             final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ?
   1046                     MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
   1047             int customNavWidth = Math.max(0,
   1048                     (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth)
   1049                     - horizontalMargin);
   1050             final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) &
   1051                     Gravity.HORIZONTAL_GRAVITY_MASK;
   1052 
   1053             // Centering a custom view is treated specially; we try to center within the whole
   1054             // action bar rather than in the available space.
   1055             if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) {
   1056                 customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2;
   1057             }
   1058 
   1059             customView.measure(
   1060                     MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode),
   1061                     MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode));
   1062             availableWidth -= horizontalMargin + customView.getMeasuredWidth();
   1063         }
   1064 
   1065         /*
   1066          * Measure the whole up container now, allowing for the full home+title sections.
   1067          * (This will re-measure the home view.)
   1068          */
   1069         availableWidth = measureChildView(mUpGoerFive, availableWidth + homeWidth,
   1070                 MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
   1071         if (mTitleLayout != null) {
   1072             leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth());
   1073         }
   1074 
   1075         if (mContentHeight <= 0) {
   1076             int measuredHeight = 0;
   1077             for (int i = 0; i < childCount; i++) {
   1078                 View v = getChildAt(i);
   1079                 int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
   1080                 if (paddedViewHeight > measuredHeight) {
   1081                     measuredHeight = paddedViewHeight;
   1082                 }
   1083             }
   1084             setMeasuredDimension(contentWidth, measuredHeight);
   1085         } else {
   1086             setMeasuredDimension(contentWidth, maxHeight);
   1087         }
   1088 
   1089         if (mContextView != null) {
   1090             mContextView.setContentHeight(getMeasuredHeight());
   1091         }
   1092 
   1093         if (mProgressView != null && mProgressView.getVisibility() != GONE) {
   1094             mProgressView.measure(MeasureSpec.makeMeasureSpec(
   1095                     contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY),
   1096                     MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST));
   1097         }
   1098     }
   1099 
   1100     @Override
   1101     protected void onLayout(boolean changed, int l, int t, int r, int b) {
   1102         final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
   1103 
   1104         if (contentHeight <= 0) {
   1105             // Nothing to do if we can't see anything.
   1106             return;
   1107         }
   1108 
   1109         final boolean isLayoutRtl = isLayoutRtl();
   1110         final int direction = isLayoutRtl ? 1 : -1;
   1111         int menuStart = isLayoutRtl ? getPaddingLeft() : r - l - getPaddingRight();
   1112         // In LTR mode, we start from left padding and go to the right; in RTL mode, we start
   1113         // from the padding right and go to the left (in reverse way)
   1114         int x = isLayoutRtl ? r - l - getPaddingRight() : getPaddingLeft();
   1115         final int y = getPaddingTop();
   1116 
   1117         HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
   1118         final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
   1119                 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
   1120         int startOffset = 0;
   1121         if (homeLayout.getParent() == mUpGoerFive) {
   1122             if (homeLayout.getVisibility() != GONE) {
   1123                 startOffset = homeLayout.getStartOffset();
   1124             } else if (showTitle) {
   1125                 startOffset = homeLayout.getUpWidth();
   1126             }
   1127         }
   1128 
   1129         // Position the up container based on where the edge of the home layout should go.
   1130         x += positionChild(mUpGoerFive,
   1131                 next(x, startOffset, isLayoutRtl), y, contentHeight, isLayoutRtl);
   1132         x = next(x, startOffset, isLayoutRtl);
   1133 
   1134         if (mExpandedActionView == null) {
   1135             switch (mNavigationMode) {
   1136                 case ActionBar.NAVIGATION_MODE_STANDARD:
   1137                     break;
   1138                 case ActionBar.NAVIGATION_MODE_LIST:
   1139                     if (mListNavLayout != null) {
   1140                         if (showTitle) {
   1141                             x = next(x, mItemPadding, isLayoutRtl);
   1142                         }
   1143                         x += positionChild(mListNavLayout, x, y, contentHeight, isLayoutRtl);
   1144                         x = next(x, mItemPadding, isLayoutRtl);
   1145                     }
   1146                     break;
   1147                 case ActionBar.NAVIGATION_MODE_TABS:
   1148                     if (mTabScrollView != null) {
   1149                         if (showTitle) x = next(x, mItemPadding, isLayoutRtl);
   1150                         x += positionChild(mTabScrollView, x, y, contentHeight, isLayoutRtl);
   1151                         x = next(x, mItemPadding, isLayoutRtl);
   1152                     }
   1153                     break;
   1154             }
   1155         }
   1156 
   1157         if (mMenuView != null && mMenuView.getParent() == this) {
   1158             positionChild(mMenuView, menuStart, y, contentHeight, !isLayoutRtl);
   1159             menuStart += direction * mMenuView.getMeasuredWidth();
   1160         }
   1161 
   1162         if (mIndeterminateProgressView != null &&
   1163                 mIndeterminateProgressView.getVisibility() != GONE) {
   1164             positionChild(mIndeterminateProgressView, menuStart, y, contentHeight, !isLayoutRtl);
   1165             menuStart += direction * mIndeterminateProgressView.getMeasuredWidth();
   1166         }
   1167 
   1168         View customView = null;
   1169         if (mExpandedActionView != null) {
   1170             customView = mExpandedActionView;
   1171         } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
   1172                 mCustomNavView != null) {
   1173             customView = mCustomNavView;
   1174         }
   1175         if (customView != null) {
   1176             final int layoutDirection = getLayoutDirection();
   1177             ViewGroup.LayoutParams lp = customView.getLayoutParams();
   1178             final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
   1179                     (ActionBar.LayoutParams) lp : null;
   1180             final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY;
   1181             final int navWidth = customView.getMeasuredWidth();
   1182 
   1183             int topMargin = 0;
   1184             int bottomMargin = 0;
   1185             if (ablp != null) {
   1186                 x = next(x, ablp.getMarginStart(), isLayoutRtl);
   1187                 menuStart += direction * ablp.getMarginEnd();
   1188                 topMargin = ablp.topMargin;
   1189                 bottomMargin = ablp.bottomMargin;
   1190             }
   1191 
   1192             int hgravity = gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
   1193             // See if we actually have room to truly center; if not push against left or right.
   1194             if (hgravity == Gravity.CENTER_HORIZONTAL) {
   1195                 final int centeredLeft = ((mRight - mLeft) - navWidth) / 2;
   1196                 if (isLayoutRtl) {
   1197                     final int centeredStart = centeredLeft + navWidth;
   1198                     final int centeredEnd = centeredLeft;
   1199                     if (centeredStart > x) {
   1200                         hgravity = Gravity.RIGHT;
   1201                     } else if (centeredEnd < menuStart) {
   1202                         hgravity = Gravity.LEFT;
   1203                     }
   1204                 } else {
   1205                     final int centeredStart = centeredLeft;
   1206                     final int centeredEnd = centeredLeft + navWidth;
   1207                     if (centeredStart < x) {
   1208                         hgravity = Gravity.LEFT;
   1209                     } else if (centeredEnd > menuStart) {
   1210                         hgravity = Gravity.RIGHT;
   1211                     }
   1212                 }
   1213             } else if (gravity == Gravity.NO_GRAVITY) {
   1214                 hgravity = Gravity.START;
   1215             }
   1216 
   1217             int xpos = 0;
   1218             switch (Gravity.getAbsoluteGravity(hgravity, layoutDirection)) {
   1219                 case Gravity.CENTER_HORIZONTAL:
   1220                     xpos = ((mRight - mLeft) - navWidth) / 2;
   1221                     break;
   1222                 case Gravity.LEFT:
   1223                     xpos = isLayoutRtl ? menuStart : x;
   1224                     break;
   1225                 case Gravity.RIGHT:
   1226                     xpos = isLayoutRtl ? x - navWidth : menuStart - navWidth;
   1227                     break;
   1228             }
   1229 
   1230             int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
   1231 
   1232             if (gravity == Gravity.NO_GRAVITY) {
   1233                 vgravity = Gravity.CENTER_VERTICAL;
   1234             }
   1235 
   1236             int ypos = 0;
   1237             switch (vgravity) {
   1238                 case Gravity.CENTER_VERTICAL:
   1239                     final int paddedTop = getPaddingTop();
   1240                     final int paddedBottom = mBottom - mTop - getPaddingBottom();
   1241                     ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2;
   1242                     break;
   1243                 case Gravity.TOP:
   1244                     ypos = getPaddingTop() + topMargin;
   1245                     break;
   1246                 case Gravity.BOTTOM:
   1247                     ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight()
   1248                             - bottomMargin;
   1249                     break;
   1250             }
   1251             final int customWidth = customView.getMeasuredWidth();
   1252             customView.layout(xpos, ypos, xpos + customWidth,
   1253                     ypos + customView.getMeasuredHeight());
   1254             x = next(x, customWidth, isLayoutRtl);
   1255         }
   1256 
   1257         if (mProgressView != null) {
   1258             mProgressView.bringToFront();
   1259             final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2;
   1260             mProgressView.layout(mProgressBarPadding, -halfProgressHeight,
   1261                     mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight);
   1262         }
   1263     }
   1264 
   1265     @Override
   1266     public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
   1267         return new ActionBar.LayoutParams(getContext(), attrs);
   1268     }
   1269 
   1270     @Override
   1271     public ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
   1272         if (lp == null) {
   1273             lp = generateDefaultLayoutParams();
   1274         }
   1275         return lp;
   1276     }
   1277 
   1278     @Override
   1279     public Parcelable onSaveInstanceState() {
   1280         Parcelable superState = super.onSaveInstanceState();
   1281         SavedState state = new SavedState(superState);
   1282 
   1283         if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) {
   1284             state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId();
   1285         }
   1286 
   1287         state.isOverflowOpen = isOverflowMenuShowing();
   1288 
   1289         return state;
   1290     }
   1291 
   1292     @Override
   1293     public void onRestoreInstanceState(Parcelable p) {
   1294         SavedState state = (SavedState) p;
   1295 
   1296         super.onRestoreInstanceState(state.getSuperState());
   1297 
   1298         if (state.expandedMenuItemId != 0 &&
   1299                 mExpandedMenuPresenter != null && mOptionsMenu != null) {
   1300             final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId);
   1301             if (item != null) {
   1302                 item.expandActionView();
   1303             }
   1304         }
   1305 
   1306         if (state.isOverflowOpen) {
   1307             postShowOverflowMenu();
   1308         }
   1309     }
   1310 
   1311     public void setNavigationIcon(Drawable indicator) {
   1312         mHomeLayout.setUpIndicator(indicator);
   1313     }
   1314 
   1315     @Override
   1316     public void setDefaultNavigationIcon(Drawable icon) {
   1317         mHomeLayout.setDefaultUpIndicator(icon);
   1318     }
   1319 
   1320     public void setNavigationIcon(int resId) {
   1321         mHomeLayout.setUpIndicator(resId);
   1322     }
   1323 
   1324     public void setNavigationContentDescription(CharSequence description) {
   1325         mHomeDescription = description;
   1326         updateHomeAccessibility(mUpGoerFive.isEnabled());
   1327     }
   1328 
   1329     public void setNavigationContentDescription(int resId) {
   1330         mHomeDescriptionRes = resId;
   1331         mHomeDescription = resId != 0 ? getResources().getText(resId) : null;
   1332         updateHomeAccessibility(mUpGoerFive.isEnabled());
   1333     }
   1334 
   1335     @Override
   1336     public void setDefaultNavigationContentDescription(int defaultNavigationContentDescription) {
   1337         if (mDefaultUpDescription == defaultNavigationContentDescription) {
   1338             return;
   1339         }
   1340         mDefaultUpDescription = defaultNavigationContentDescription;
   1341         updateHomeAccessibility(mUpGoerFive.isEnabled());
   1342     }
   1343 
   1344     @Override
   1345     public void setMenuCallbacks(MenuPresenter.Callback presenterCallback,
   1346             MenuBuilder.Callback menuBuilderCallback) {
   1347         if (mActionMenuPresenter != null) {
   1348             mActionMenuPresenter.setCallback(presenterCallback);
   1349         }
   1350         if (mOptionsMenu != null) {
   1351             mOptionsMenu.setCallback(menuBuilderCallback);
   1352         }
   1353     }
   1354 
   1355     @Override
   1356     public Menu getMenu() {
   1357         return mOptionsMenu;
   1358     }
   1359 
   1360     static class SavedState extends BaseSavedState {
   1361         int expandedMenuItemId;
   1362         boolean isOverflowOpen;
   1363 
   1364         SavedState(Parcelable superState) {
   1365             super(superState);
   1366         }
   1367 
   1368         private SavedState(Parcel in) {
   1369             super(in);
   1370             expandedMenuItemId = in.readInt();
   1371             isOverflowOpen = in.readInt() != 0;
   1372         }
   1373 
   1374         @Override
   1375         public void writeToParcel(Parcel out, int flags) {
   1376             super.writeToParcel(out, flags);
   1377             out.writeInt(expandedMenuItemId);
   1378             out.writeInt(isOverflowOpen ? 1 : 0);
   1379         }
   1380 
   1381         public static final Parcelable.Creator<SavedState> CREATOR =
   1382                 new Parcelable.Creator<SavedState>() {
   1383             public SavedState createFromParcel(Parcel in) {
   1384                 return new SavedState(in);
   1385             }
   1386 
   1387             public SavedState[] newArray(int size) {
   1388                 return new SavedState[size];
   1389             }
   1390         };
   1391     }
   1392 
   1393     private static class HomeView extends FrameLayout {
   1394         private ImageView mUpView;
   1395         private ImageView mIconView;
   1396         private int mUpWidth;
   1397         private int mStartOffset;
   1398         private int mUpIndicatorRes;
   1399         private Drawable mDefaultUpIndicator;
   1400         private Drawable mUpIndicator;
   1401 
   1402         private static final long DEFAULT_TRANSITION_DURATION = 150;
   1403 
   1404         public HomeView(Context context) {
   1405             this(context, null);
   1406         }
   1407 
   1408         public HomeView(Context context, AttributeSet attrs) {
   1409             super(context, attrs);
   1410             LayoutTransition t = getLayoutTransition();
   1411             if (t != null) {
   1412                 // Set a lower duration than the default
   1413                 t.setDuration(DEFAULT_TRANSITION_DURATION);
   1414             }
   1415         }
   1416 
   1417         public void setShowUp(boolean isUp) {
   1418             mUpView.setVisibility(isUp ? VISIBLE : GONE);
   1419         }
   1420 
   1421         public void setShowIcon(boolean showIcon) {
   1422             mIconView.setVisibility(showIcon ? VISIBLE : GONE);
   1423         }
   1424 
   1425         public void setIcon(Drawable icon) {
   1426             mIconView.setImageDrawable(icon);
   1427         }
   1428 
   1429         public void setUpIndicator(Drawable d) {
   1430             mUpIndicator = d;
   1431             mUpIndicatorRes = 0;
   1432             updateUpIndicator();
   1433         }
   1434 
   1435         public void setDefaultUpIndicator(Drawable d) {
   1436             mDefaultUpIndicator = d;
   1437             updateUpIndicator();
   1438         }
   1439 
   1440         public void setUpIndicator(int resId) {
   1441             mUpIndicatorRes = resId;
   1442             mUpIndicator = null;
   1443             updateUpIndicator();
   1444         }
   1445 
   1446         private void updateUpIndicator() {
   1447             if (mUpIndicator != null) {
   1448                 mUpView.setImageDrawable(mUpIndicator);
   1449             } else if (mUpIndicatorRes != 0) {
   1450                 mUpView.setImageDrawable(getContext().getDrawable(mUpIndicatorRes));
   1451             } else {
   1452                 mUpView.setImageDrawable(mDefaultUpIndicator);
   1453             }
   1454         }
   1455 
   1456         @Override
   1457         protected void onConfigurationChanged(Configuration newConfig) {
   1458             super.onConfigurationChanged(newConfig);
   1459             if (mUpIndicatorRes != 0) {
   1460                 // Reload for config change
   1461                 updateUpIndicator();
   1462             }
   1463         }
   1464 
   1465         @Override
   1466         public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
   1467             onPopulateAccessibilityEvent(event);
   1468             return true;
   1469         }
   1470 
   1471         @Override
   1472         public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
   1473             super.onPopulateAccessibilityEvent(event);
   1474             final CharSequence cdesc = getContentDescription();
   1475             if (!TextUtils.isEmpty(cdesc)) {
   1476                 event.getText().add(cdesc);
   1477             }
   1478         }
   1479 
   1480         @Override
   1481         public boolean dispatchHoverEvent(MotionEvent event) {
   1482             // Don't allow children to hover; we want this to be treated as a single component.
   1483             return onHoverEvent(event);
   1484         }
   1485 
   1486         @Override
   1487         protected void onFinishInflate() {
   1488             mUpView = (ImageView) findViewById(com.android.internal.R.id.up);
   1489             mIconView = (ImageView) findViewById(com.android.internal.R.id.home);
   1490             mDefaultUpIndicator = mUpView.getDrawable();
   1491         }
   1492 
   1493         public int getStartOffset() {
   1494             return mUpView.getVisibility() == GONE ? mStartOffset : 0;
   1495         }
   1496 
   1497         public int getUpWidth() {
   1498             return mUpWidth;
   1499         }
   1500 
   1501         @Override
   1502         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   1503             measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0);
   1504             final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
   1505             final int upMargins = upLp.leftMargin + upLp.rightMargin;
   1506             mUpWidth = mUpView.getMeasuredWidth();
   1507             mStartOffset = mUpWidth + upMargins;
   1508             int width = mUpView.getVisibility() == GONE ? 0 : mStartOffset;
   1509             int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin;
   1510 
   1511             if (mIconView.getVisibility() != GONE) {
   1512                 measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0);
   1513                 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
   1514                 width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin;
   1515                 height = Math.max(height,
   1516                         iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin);
   1517             } else if (upMargins < 0) {
   1518                 // Remove the measurement effects of negative margins used for offsets
   1519                 width -= upMargins;
   1520             }
   1521 
   1522             final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
   1523             final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
   1524             final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
   1525             final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
   1526 
   1527             switch (widthMode) {
   1528                 case MeasureSpec.AT_MOST:
   1529                     width = Math.min(width, widthSize);
   1530                     break;
   1531                 case MeasureSpec.EXACTLY:
   1532                     width = widthSize;
   1533                     break;
   1534                 case MeasureSpec.UNSPECIFIED:
   1535                 default:
   1536                     break;
   1537             }
   1538             switch (heightMode) {
   1539                 case MeasureSpec.AT_MOST:
   1540                     height = Math.min(height, heightSize);
   1541                     break;
   1542                 case MeasureSpec.EXACTLY:
   1543                     height = heightSize;
   1544                     break;
   1545                 case MeasureSpec.UNSPECIFIED:
   1546                 default:
   1547                     break;
   1548             }
   1549             setMeasuredDimension(width, height);
   1550         }
   1551 
   1552         @Override
   1553         protected void onLayout(boolean changed, int l, int t, int r, int b) {
   1554             final int vCenter = (b - t) / 2;
   1555             final boolean isLayoutRtl = isLayoutRtl();
   1556             final int width = getWidth();
   1557             int upOffset = 0;
   1558             if (mUpView.getVisibility() != GONE) {
   1559                 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
   1560                 final int upHeight = mUpView.getMeasuredHeight();
   1561                 final int upWidth = mUpView.getMeasuredWidth();
   1562                 upOffset = upLp.leftMargin + upWidth + upLp.rightMargin;
   1563                 final int upTop = vCenter - upHeight / 2;
   1564                 final int upBottom = upTop + upHeight;
   1565                 final int upRight;
   1566                 final int upLeft;
   1567                 if (isLayoutRtl) {
   1568                     upRight = width;
   1569                     upLeft = upRight - upWidth;
   1570                     r -= upOffset;
   1571                 } else {
   1572                     upRight = upWidth;
   1573                     upLeft = 0;
   1574                     l += upOffset;
   1575                 }
   1576                 mUpView.layout(upLeft, upTop, upRight, upBottom);
   1577             }
   1578 
   1579             final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
   1580             final int iconHeight = mIconView.getMeasuredHeight();
   1581             final int iconWidth = mIconView.getMeasuredWidth();
   1582             final int hCenter = (r - l) / 2;
   1583             final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2);
   1584             final int iconBottom = iconTop + iconHeight;
   1585             final int iconLeft;
   1586             final int iconRight;
   1587             int marginStart = iconLp.getMarginStart();
   1588             final int delta = Math.max(marginStart, hCenter - iconWidth / 2);
   1589             if (isLayoutRtl) {
   1590                 iconRight = width - upOffset - delta;
   1591                 iconLeft = iconRight - iconWidth;
   1592             } else {
   1593                 iconLeft = upOffset + delta;
   1594                 iconRight = iconLeft + iconWidth;
   1595             }
   1596             mIconView.layout(iconLeft, iconTop, iconRight, iconBottom);
   1597         }
   1598     }
   1599 
   1600     private class ExpandedActionViewMenuPresenter implements MenuPresenter {
   1601         MenuBuilder mMenu;
   1602         MenuItemImpl mCurrentExpandedItem;
   1603 
   1604         @Override
   1605         public void initForMenu(Context context, MenuBuilder menu) {
   1606             // Clear the expanded action view when menus change.
   1607             if (mMenu != null && mCurrentExpandedItem != null) {
   1608                 mMenu.collapseItemActionView(mCurrentExpandedItem);
   1609             }
   1610             mMenu = menu;
   1611         }
   1612 
   1613         @Override
   1614         public MenuView getMenuView(ViewGroup root) {
   1615             return null;
   1616         }
   1617 
   1618         @Override
   1619         public void updateMenuView(boolean cleared) {
   1620             // Make sure the expanded item we have is still there.
   1621             if (mCurrentExpandedItem != null) {
   1622                 boolean found = false;
   1623 
   1624                 if (mMenu != null) {
   1625                     final int count = mMenu.size();
   1626                     for (int i = 0; i < count; i++) {
   1627                         final MenuItem item = mMenu.getItem(i);
   1628                         if (item == mCurrentExpandedItem) {
   1629                             found = true;
   1630                             break;
   1631                         }
   1632                     }
   1633                 }
   1634 
   1635                 if (!found) {
   1636                     // The item we had expanded disappeared. Collapse.
   1637                     collapseItemActionView(mMenu, mCurrentExpandedItem);
   1638                 }
   1639             }
   1640         }
   1641 
   1642         @Override
   1643         public void setCallback(Callback cb) {
   1644         }
   1645 
   1646         @Override
   1647         public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
   1648             return false;
   1649         }
   1650 
   1651         @Override
   1652         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
   1653         }
   1654 
   1655         @Override
   1656         public boolean flagActionItems() {
   1657             return false;
   1658         }
   1659 
   1660         @Override
   1661         public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
   1662             ActionBarTransition.beginDelayedTransition(ActionBarView.this);
   1663 
   1664             mExpandedActionView = item.getActionView();
   1665             mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
   1666             mCurrentExpandedItem = item;
   1667             if (mExpandedActionView.getParent() != ActionBarView.this) {
   1668                 addView(mExpandedActionView);
   1669             }
   1670             if (mExpandedHomeLayout.getParent() != mUpGoerFive) {
   1671                 mUpGoerFive.addView(mExpandedHomeLayout);
   1672             }
   1673             mHomeLayout.setVisibility(GONE);
   1674             if (mTitleLayout != null) mTitleLayout.setVisibility(GONE);
   1675             if (mTabScrollView != null) mTabScrollView.setVisibility(GONE);
   1676             if (mSpinner != null) mSpinner.setVisibility(GONE);
   1677             if (mCustomNavView != null) mCustomNavView.setVisibility(GONE);
   1678             setHomeButtonEnabled(false, false);
   1679             requestLayout();
   1680             item.setActionViewExpanded(true);
   1681 
   1682             if (mExpandedActionView instanceof CollapsibleActionView) {
   1683                 ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
   1684             }
   1685 
   1686             return true;
   1687         }
   1688 
   1689         @Override
   1690         public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
   1691             ActionBarTransition.beginDelayedTransition(ActionBarView.this);
   1692 
   1693             // Do this before detaching the actionview from the hierarchy, in case
   1694             // it needs to dismiss the soft keyboard, etc.
   1695             if (mExpandedActionView instanceof CollapsibleActionView) {
   1696                 ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
   1697             }
   1698 
   1699             removeView(mExpandedActionView);
   1700             mUpGoerFive.removeView(mExpandedHomeLayout);
   1701             mExpandedActionView = null;
   1702             if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) {
   1703                 mHomeLayout.setVisibility(VISIBLE);
   1704             }
   1705             if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
   1706                 if (mTitleLayout == null) {
   1707                     initTitle();
   1708                 } else {
   1709                     mTitleLayout.setVisibility(VISIBLE);
   1710                 }
   1711             }
   1712             if (mTabScrollView != null) mTabScrollView.setVisibility(VISIBLE);
   1713             if (mSpinner != null) mSpinner.setVisibility(VISIBLE);
   1714             if (mCustomNavView != null) mCustomNavView.setVisibility(VISIBLE);
   1715 
   1716             mExpandedHomeLayout.setIcon(null);
   1717             mCurrentExpandedItem = null;
   1718             setHomeButtonEnabled(mWasHomeEnabled); // Set by expandItemActionView above
   1719             requestLayout();
   1720             item.setActionViewExpanded(false);
   1721 
   1722             return true;
   1723         }
   1724 
   1725         @Override
   1726         public int getId() {
   1727             return 0;
   1728         }
   1729 
   1730         @Override
   1731         public Parcelable onSaveInstanceState() {
   1732             return null;
   1733         }
   1734 
   1735         @Override
   1736         public void onRestoreInstanceState(Parcelable state) {
   1737         }
   1738     }
   1739 }
   1740