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