Project: ActionBarSherlock
Code Examples
/*
 * Copyright (C) 2010 The Android Open Source Project 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
 
package com.actionbarsherlock.internal.widget; 
 
import org.xmlpull.v1.XmlPullParser; 
import android.app.Activity; 
import android.content.Context; 
import android.content.pm.ApplicationInfo; 
import android.content.pm.PackageManager; 
import android.content.pm.PackageManager.NameNotFoundException; 
import android.content.res.AssetManager; 
import android.content.res.Configuration; 
import android.content.res.TypedArray; 
import android.content.res.XmlResourceParser; 
import android.graphics.drawable.Drawable; 
import android.os.Build; 
import android.os.Parcel; 
import android.os.Parcelable; 
import android.text.TextUtils; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.ViewParent; 
import android.view.accessibility.AccessibilityEvent; 
import android.widget.FrameLayout; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.SpinnerAdapter; 
import android.widget.TextView; 
 
import com.actionbarsherlock.R; 
import com.actionbarsherlock.app.ActionBar; 
import com.actionbarsherlock.app.ActionBar.OnNavigationListener; 
import com.actionbarsherlock.internal.ActionBarSherlockCompat; 
import com.actionbarsherlock.internal.view.menu.ActionMenuItem; 
import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; 
import com.actionbarsherlock.internal.view.menu.ActionMenuView; 
import com.actionbarsherlock.internal.view.menu.MenuBuilder; 
import com.actionbarsherlock.internal.view.menu.MenuItemImpl; 
import com.actionbarsherlock.internal.view.menu.MenuPresenter; 
import com.actionbarsherlock.internal.view.menu.MenuView; 
import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; 
import com.actionbarsherlock.view.CollapsibleActionView; 
import com.actionbarsherlock.view.Menu; 
import com.actionbarsherlock.view.MenuItem; 
import com.actionbarsherlock.view.Window; 
 
import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; 
 
/**
 * @hide 
 */
 
public class ActionBarView extends AbsActionBarView { 
    private static final String TAG = "ActionBarView"
    private static final boolean DEBUG = false
 
    /**
     * Display options applied by default 
     */
 
    public static final int DISPLAY_DEFAULT = 0
 
    /**
     * Display options that require re-layout as opposed to a simple invalidate 
     */
 
    private static final int DISPLAY_RELAYOUT_MASK = 
            ActionBar.DISPLAY_SHOW_HOME | 
            ActionBar.DISPLAY_USE_LOGO | 
            ActionBar.DISPLAY_HOME_AS_UP | 
            ActionBar.DISPLAY_SHOW_CUSTOM | 
            ActionBar.DISPLAY_SHOW_TITLE; 
 
    private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.LEFT | Gravity.CENTER_VERTICAL; 
 
    private int mNavigationMode; 
    private int mDisplayOptions = -1
    private CharSequence mTitle; 
    private CharSequence mSubtitle; 
    private Drawable mIcon; 
    private Drawable mLogo; 
 
    private HomeView mHomeLayout; 
    private HomeView mExpandedHomeLayout; 
    private LinearLayout mTitleLayout; 
    private TextView mTitleView; 
    private TextView mSubtitleView; 
    private View mTitleUpView; 
 
    private IcsSpinner mSpinner; 
    private IcsLinearLayout mListNavLayout; 
    private ScrollingTabContainerView mTabScrollView; 
    private View mCustomNavView; 
    private IcsProgressBar mProgressView; 
    private IcsProgressBar mIndeterminateProgressView; 
 
    private int mProgressBarPadding; 
    private int mItemPadding; 
 
    private int mTitleStyleRes; 
    private int mSubtitleStyleRes; 
    private int mProgressStyle; 
    private int mIndeterminateProgressStyle; 
 
    private boolean mUserTitle; 
    private boolean mIncludeTabs; 
    private boolean mIsCollapsable; 
    private boolean mIsCollapsed; 
 
    private MenuBuilder mOptionsMenu; 
 
    private ActionBarContextView mContextView; 
 
    private ActionMenuItem mLogoNavItem; 
 
    private SpinnerAdapter mSpinnerAdapter; 
    private OnNavigationListener mCallback; 
 
    //UNUSED private Runnable mTabSelector; 
 
    private ExpandedActionViewMenuPresenter mExpandedMenuPresenter; 
    View mExpandedActionView; 
 
    Window.Callback mWindowCallback; 
 
    @SuppressWarnings("rawtypes"
    private final IcsAdapterView.OnItemSelectedListener mNavItemSelectedListener = 
            new IcsAdapterView.OnItemSelectedListener() { 
        public void onItemSelected(IcsAdapterView parent, View view, int position, long id) { 
            if (mCallback != null) { 
                mCallback.onNavigationItemSelected(position, id); 
            } 
        } 
        public void onNothingSelected(IcsAdapterView parent) { 
            // Do nothing 
        } 
    }; 
 
    private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() { 
        @Override 
        public void onClick(View v) { 
            final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem; 
            if (item != null) { 
                item.collapseActionView(); 
            } 
        } 
    }; 
 
    private final OnClickListener mUpClickListener = new OnClickListener() { 
        public void onClick(View v) { 
            mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem); 
        } 
    }; 
 
    public ActionBarView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
 
        // Background is always provided by the container. 
        setBackgroundResource(0); 
 
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockActionBar, 
                R.attr.actionBarStyle, 0); 
 
        ApplicationInfo appInfo = context.getApplicationInfo(); 
        PackageManager pm = context.getPackageManager(); 
        mNavigationMode = a.getInt(R.styleable.SherlockActionBar_navigationMode, 
                ActionBar.NAVIGATION_MODE_STANDARD); 
        mTitle = a.getText(R.styleable.SherlockActionBar_title); 
        mSubtitle = a.getText(R.styleable.SherlockActionBar_subtitle); 
 
        mLogo = a.getDrawable(R.styleable.SherlockActionBar_logo); 
        if (mLogo == null) { 
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
                if (context instanceof Activity) { 
                    //Even though native methods existed in API 9 and 10 they don't work 
                    //so just parse the manifest to look for the logo pre-Honeycomb 
                    final int resId = loadLogoFromManifest((Activity) context); 
                    if (resId != 0) { 
                        mLogo = context.getResources().getDrawable(resId); 
                    } 
                } 
            } else { 
                if (context instanceof Activity) { 
                    try { 
                        mLogo = pm.getActivityLogo(((Activity) context).getComponentName()); 
                    } catch (NameNotFoundException e) { 
                        Log.e(TAG, "Activity component name not found!", e); 
                    } 
                } 
                if (mLogo == null) { 
                    mLogo = appInfo.loadLogo(pm); 
                } 
            } 
        } 
 
        mIcon = a.getDrawable(R.styleable.SherlockActionBar_icon); 
        if (mIcon == null) { 
            if (context instanceof Activity) { 
                try { 
                    mIcon = pm.getActivityIcon(((Activity) context).getComponentName()); 
                } catch (NameNotFoundException e) { 
                    Log.e(TAG, "Activity component name not found!", e); 
                } 
            } 
            if (mIcon == null) { 
                mIcon = appInfo.loadIcon(pm); 
            } 
        } 
 
        final LayoutInflater inflater = LayoutInflater.from(context); 
 
        final int homeResId = a.getResourceId( 
                R.styleable.SherlockActionBar_homeLayout, 
                R.layout.abs__action_bar_home); 
 
        mHomeLayout = (HomeView) inflater.inflate(homeResId, thisfalse); 
 
        mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, thisfalse); 
        mExpandedHomeLayout.setUp(true); 
        mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener); 
        mExpandedHomeLayout.setContentDescription(getResources().getText( 
                R.string.abs__action_bar_up_description)); 
 
        mTitleStyleRes = a.getResourceId(R.styleable.SherlockActionBar_titleTextStyle, 0); 
        mSubtitleStyleRes = a.getResourceId(R.styleable.SherlockActionBar_subtitleTextStyle, 0); 
        mProgressStyle = a.getResourceId(R.styleable.SherlockActionBar_progressBarStyle, 0); 
        mIndeterminateProgressStyle = a.getResourceId( 
                R.styleable.SherlockActionBar_indeterminateProgressStyle, 0); 
 
        mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.SherlockActionBar_progressBarPadding, 0); 
        mItemPadding = a.getDimensionPixelOffset(R.styleable.SherlockActionBar_itemPadding, 0); 
 
        setDisplayOptions(a.getInt(R.styleable.SherlockActionBar_displayOptions, DISPLAY_DEFAULT)); 
 
        final int customNavId = a.getResourceId(R.styleable.SherlockActionBar_customNavigationLayout, 0); 
        if (customNavId != 0) { 
            mCustomNavView = inflater.inflate(customNavId, thisfalse); 
            mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD; 
            setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM); 
        } 
 
        mContentHeight = a.getLayoutDimension(R.styleable.SherlockActionBar_height, 0); 
 
        a.recycle(); 
 
        mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 00, mTitle); 
        mHomeLayout.setOnClickListener(mUpClickListener); 
        mHomeLayout.setClickable(true); 
        mHomeLayout.setFocusable(true); 
    } 
 
    /**
     * Attempt to programmatically load the logo from the manifest file of an 
     * activity by using an XML pull parser. This should allow us to read the 
     * logo attribute regardless of the platform it is being run on. 
     * 
     * @param activity Activity instance. 
     * @return Logo resource ID. 
     */
 
    private static int loadLogoFromManifest(Activity activity) { 
        int logo = 0
        try { 
            final String thisPackage = activity.getClass().getName(); 
            if (DEBUG) Log.i(TAG, "Parsing AndroidManifest.xml for " + thisPackage); 
 
            final String packageName = activity.getApplicationInfo().packageName; 
            final AssetManager am = activity.createPackageContext(packageName, 0).getAssets(); 
            final XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); 
 
            int eventType = xml.getEventType(); 
            while (eventType != XmlPullParser.END_DOCUMENT) { 
                if (eventType == XmlPullParser.START_TAG) { 
                    String name = xml.getName(); 
 
                    if ("application".equals(name)) { 
                        //Check if the <application> has the attribute 
                        if (DEBUG) Log.d(TAG, "Got <application>"); 
 
                        for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { 
                            if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); 
 
                            if ("logo".equals(xml.getAttributeName(i))) { 
                                logo = xml.getAttributeResourceValue(i, 0); 
                                break//out of for loop 
                            } 
                        } 
                    } else if ("activity".equals(name)) { 
                        //Check if the <activity> is us and has the attribute 
                        if (DEBUG) Log.d(TAG, "Got <activity>"); 
                        Integer activityLogo = null
                        String activityPackage = null
                        boolean isOurActivity = false
 
                        for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { 
                            if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); 
 
                            //We need both uiOptions and name attributes 
                            String attrName = xml.getAttributeName(i); 
                            if ("logo".equals(attrName)) { 
                                activityLogo = xml.getAttributeResourceValue(i, 0); 
                            } else if ("name".equals(attrName)) { 
                                activityPackage = ActionBarSherlockCompat.cleanActivityName(packageName, xml.getAttributeValue(i)); 
                                if (!thisPackage.equals(activityPackage)) { 
                                    break//on to the next 
                                } 
                                isOurActivity = true
                            } 
 
                            //Make sure we have both attributes before processing 
                            if ((activityLogo != null) && (activityPackage != null)) { 
                                //Our activity, logo specified, override with our value 
                                logo = activityLogo.intValue(); 
                            } 
                        } 
                        if (isOurActivity) { 
                            //If we matched our activity but it had no logo don't 
                            //do any more processing of the manifest 
                            break
                        } 
                    } 
                } 
                eventType = xml.nextToken(); 
            } 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
        if (DEBUG) Log.i(TAG, "Returning " + Integer.toHexString(logo)); 
        return logo; 
    } 
 
    /*
     * Must be public so we can dispatch pre-2.2 via ActionBarImpl. 
     */
 
    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
        super.onConfigurationChanged(newConfig); 
 
        mTitleView = null
        mSubtitleView = null
        mTitleUpView = null
        if (mTitleLayout != null && mTitleLayout.getParent() == this) { 
            removeView(mTitleLayout); 
        } 
        mTitleLayout = null
        if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { 
            initTitle(); 
        } 
 
        if (mTabScrollView != null && mIncludeTabs) { 
            ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams(); 
            if (lp != null) { 
                lp.width = LayoutParams.WRAP_CONTENT; 
                lp.height = LayoutParams.MATCH_PARENT; 
            } 
            mTabScrollView.setAllowCollapse(true); 
        } 
    } 
 
    /**
     * Set the window callback used to invoke menu items; used for dispatching home button presses. 
     * @param cb Window callback to dispatch to 
     */
 
    public void setWindowCallback(Window.Callback cb) { 
        mWindowCallback = cb; 
    } 
 
    @Override 
    public void onDetachedFromWindow() { 
        super.onDetachedFromWindow(); 
        //UNUSED removeCallbacks(mTabSelector); 
        if (mActionMenuPresenter != null) { 
            mActionMenuPresenter.hideOverflowMenu(); 
            mActionMenuPresenter.hideSubMenus(); 
        } 
    } 
 
    @Override 
    public boolean shouldDelayChildPressedState() { 
        return false
    } 
 
    public void initProgress() { 
        mProgressView = new IcsProgressBar(mContext, null0, mProgressStyle); 
        mProgressView.setId(R.id.abs__progress_horizontal); 
        mProgressView.setMax(10000); 
        addView(mProgressView); 
    } 
 
    public void initIndeterminateProgress() { 
        mIndeterminateProgressView = new IcsProgressBar(mContext, null0, mIndeterminateProgressStyle); 
        mIndeterminateProgressView.setId(R.id.abs__progress_circular); 
        addView(mIndeterminateProgressView); 
    } 
 
    @Override 
    public void setSplitActionBar(boolean splitActionBar) { 
        if (mSplitActionBar != splitActionBar) { 
            if (mMenuView != null) { 
                final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); 
                if (oldParent != null) { 
                    oldParent.removeView(mMenuView); 
                } 
                if (splitActionBar) { 
                    if (mSplitView != null) { 
                        mSplitView.addView(mMenuView); 
                    } 
                } else { 
                    addView(mMenuView); 
                } 
            } 
            if (mSplitView != null) { 
                mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE); 
            } 
            super.setSplitActionBar(splitActionBar); 
        } 
    } 
 
    public boolean isSplitActionBar() { 
        return mSplitActionBar; 
    } 
 
    public boolean hasEmbeddedTabs() { 
        return mIncludeTabs; 
    } 
 
    public void setEmbeddedTabView(ScrollingTabContainerView tabs) { 
        if (mTabScrollView != null) { 
            removeView(mTabScrollView); 
        } 
        mTabScrollView = tabs; 
        mIncludeTabs = tabs != null
        if (mIncludeTabs && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { 
            addView(mTabScrollView); 
            ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams(); 
            lp.width = LayoutParams.WRAP_CONTENT; 
            lp.height = LayoutParams.MATCH_PARENT; 
            tabs.setAllowCollapse(true); 
        } 
    } 
 
    public void setCallback(OnNavigationListener callback) { 
        mCallback = callback; 
    } 
 
    public void setMenu(Menu menu, MenuPresenter.Callback cb) { 
        if (menu == mOptionsMenu) return
 
        if (mOptionsMenu != null) { 
            mOptionsMenu.removeMenuPresenter(mActionMenuPresenter); 
            mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter); 
        } 
 
        MenuBuilder builder = (MenuBuilder) menu; 
        mOptionsMenu = builder; 
        if (mMenuView != null) { 
            final ViewGroup oldParent = (ViewGroup) mMenuView.getParent(); 
            if (oldParent != null) { 
                oldParent.removeView(mMenuView); 
            } 
        } 
        if (mActionMenuPresenter == null) { 
            mActionMenuPresenter = new ActionMenuPresenter(mContext); 
            mActionMenuPresenter.setCallback(cb); 
            mActionMenuPresenter.setId(R.id.abs__action_menu_presenter); 
            mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter(); 
        } 
 
        ActionMenuView menuView; 
        final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, 
                LayoutParams.MATCH_PARENT); 
        if (!mSplitActionBar) { 
            mActionMenuPresenter.setExpandedActionViewsExclusive( 
                    getResources_getBoolean(getContext(), 
                    R.bool.abs__action_bar_expanded_action_views_exclusive)); 
            configPresenters(builder); 
            menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); 
            final ViewGroup oldParent = (ViewGroup) menuView.getParent(); 
            if (oldParent != null && oldParent != this) { 
                oldParent.removeView(menuView); 
            } 
            addView(menuView, layoutParams); 
        } else { 
            mActionMenuPresenter.setExpandedActionViewsExclusive(false); 
            // Allow full screen width in split mode. 
            mActionMenuPresenter.setWidthLimit( 
                    getContext().getResources().getDisplayMetrics().widthPixels, true); 
            // No limit to the item count; use whatever will fit. 
            mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); 
            // Span the whole width 
            layoutParams.width = LayoutParams.MATCH_PARENT; 
            configPresenters(builder); 
            menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); 
            if (mSplitView != null) { 
                final ViewGroup oldParent = (ViewGroup) menuView.getParent(); 
                if (oldParent != null && oldParent != mSplitView) { 
                    oldParent.removeView(menuView); 
                } 
                menuView.setVisibility(getAnimatedVisibility()); 
                mSplitView.addView(menuView, layoutParams); 
            } else { 
                // We'll add this later if we missed it this time. 
                menuView.setLayoutParams(layoutParams); 
            } 
        } 
        mMenuView = menuView; 
    } 
 
    private void configPresenters(MenuBuilder builder) { 
        if (builder != null) { 
            builder.addMenuPresenter(mActionMenuPresenter); 
            builder.addMenuPresenter(mExpandedMenuPresenter); 
        } else { 
            mActionMenuPresenter.initForMenu(mContext, null); 
            mExpandedMenuPresenter.initForMenu(mContext, null); 
            mActionMenuPresenter.updateMenuView(true); 
            mExpandedMenuPresenter.updateMenuView(true); 
        } 
    } 
 
    public boolean hasExpandedActionView() { 
        return mExpandedMenuPresenter != null && 
                mExpandedMenuPresenter.mCurrentExpandedItem != null
    } 
 
    public void collapseActionView() { 
        final MenuItemImpl item = mExpandedMenuPresenter == null ? null : 
                mExpandedMenuPresenter.mCurrentExpandedItem; 
        if (item != null) { 
            item.collapseActionView(); 
        } 
    } 
 
    public void setCustomNavigationView(View view) { 
        final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0
        if (mCustomNavView != null && showCustom) { 
            removeView(mCustomNavView); 
        } 
        mCustomNavView = view; 
        if (mCustomNavView != null && showCustom) { 
            addView(mCustomNavView); 
        } 
    } 
 
    public CharSequence getTitle() { 
        return mTitle; 
    } 
 
    /**
     * Set the action bar title. This will always replace or override window titles. 
     * @param title Title to set 
     * 
     * @see #setWindowTitle(CharSequence) 
     */
 
    public void setTitle(CharSequence title) { 
        mUserTitle = true
        setTitleImpl(title); 
    } 
 
    /**
     * Set the window title. A window title will always be replaced or overridden by a user title. 
     * @param title Title to set 
     * 
     * @see #setTitle(CharSequence) 
     */
 
    public void setWindowTitle(CharSequence title) { 
        if (!mUserTitle) { 
            setTitleImpl(title); 
        } 
    } 
 
    private void setTitleImpl(CharSequence title) { 
        mTitle = title; 
        if (mTitleView != null) { 
            mTitleView.setText(title); 
            final boolean visible = mExpandedActionView == null && 
                    (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 && 
                    (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle)); 
            mTitleLayout.setVisibility(visible ? VISIBLE : GONE); 
        } 
        if (mLogoNavItem != null) { 
            mLogoNavItem.setTitle(title); 
        } 
    } 
 
    public CharSequence getSubtitle() { 
        return mSubtitle; 
    } 
 
    public void setSubtitle(CharSequence subtitle) { 
        mSubtitle = subtitle; 
        if (mSubtitleView != null) { 
            mSubtitleView.setText(subtitle); 
            mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE); 
            final boolean visible = mExpandedActionView == null && 
                    (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 && 
                    (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle)); 
            mTitleLayout.setVisibility(visible ? VISIBLE : GONE); 
        } 
    } 
 
    public void setHomeButtonEnabled(boolean enable) { 
        mHomeLayout.setEnabled(enable); 
        mHomeLayout.setFocusable(enable); 
        // Make sure the home button has an accurate content description for accessibility. 
        if (!enable) { 
            mHomeLayout.setContentDescription(null); 
        } else if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) { 
            mHomeLayout.setContentDescription(mContext.getResources().getText( 
                    R.string.abs__action_bar_up_description)); 
        } else { 
            mHomeLayout.setContentDescription(mContext.getResources().getText( 
                    R.string.abs__action_bar_home_description)); 
        } 
    } 
 
    public void setDisplayOptions(int options) { 
        final int flagsChanged = mDisplayOptions == -1 ? -1 : options ^ mDisplayOptions; 
        mDisplayOptions = options; 
 
        if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) { 
            final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0
            final int vis = showHome && mExpandedActionView == null ? VISIBLE : GONE; 
            mHomeLayout.setVisibility(vis); 
 
            if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) { 
                final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0
                mHomeLayout.setUp(setUp); 
 
                // Showing home as up implicitly enables interaction with it. 
                // In honeycomb it was always enabled, so make this transition 
                // a bit easier for developers in the common case. 
                // (It would be silly to show it as up without responding to it.) 
                if (setUp) { 
                    setHomeButtonEnabled(true); 
                } 
            } 
 
            if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) { 
                final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0
                mHomeLayout.setIcon(logoVis ? mLogo : mIcon); 
            } 
 
            if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) { 
                if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) { 
                    initTitle(); 
                } else { 
                    removeView(mTitleLayout); 
                } 
            } 
 
            if (mTitleLayout != null && (flagsChanged & 
                    (ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) { 
                final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0
                mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE); 
                mTitleLayout.setEnabled(!showHome && homeAsUp); 
            } 
 
            if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { 
                if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { 
                    addView(mCustomNavView); 
                } else { 
                    removeView(mCustomNavView); 
                } 
            } 
 
            requestLayout(); 
        } else { 
            invalidate(); 
        } 
 
        // Make sure the home button has an accurate content description for accessibility. 
        if (!mHomeLayout.isEnabled()) { 
            mHomeLayout.setContentDescription(null); 
        } else if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) { 
            mHomeLayout.setContentDescription(mContext.getResources().getText( 
                    R.string.abs__action_bar_up_description)); 
        } else { 
            mHomeLayout.setContentDescription(mContext.getResources().getText( 
                    R.string.abs__action_bar_home_description)); 
        } 
    } 
 
    public void setIcon(Drawable icon) { 
        mIcon = icon; 
        if (icon != null && 
                ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) { 
            mHomeLayout.setIcon(icon); 
        } 
    } 
 
    public void setIcon(int resId) { 
        setIcon(mContext.getResources().getDrawable(resId)); 
    } 
 
    public void (Drawable logo) { 
        mLogo = logo; 
        if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) { 
            mHomeLayout.setIcon(logo); 
        } 
    } 
 
    public void setLogo(int resId) { 
        setLogo(mContext.getResources().getDrawable(resId)); 
    } 
 
    public void setNavigationMode(int mode) { 
        final int oldMode = mNavigationMode; 
        if (mode != oldMode) { 
            switch (oldMode) { 
            case ActionBar.NAVIGATION_MODE_LIST: 
                if (mListNavLayout != null) { 
                    removeView(mListNavLayout); 
                } 
                break
            case ActionBar.NAVIGATION_MODE_TABS: 
                if (mTabScrollView != null && mIncludeTabs) { 
                    removeView(mTabScrollView); 
                } 
            } 
 
            switch (mode) { 
            case ActionBar.NAVIGATION_MODE_LIST: 
                if (mSpinner == null) { 
                    mSpinner = new IcsSpinner(mContext, null
                            R.attr.actionDropDownStyle); 
                    mListNavLayout = (IcsLinearLayout) LayoutInflater.from(mContext) 
                            .inflate(R.layout.abs__action_bar_tab_bar_view, null); 
                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( 
                            LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); 
                    params.gravity = Gravity.CENTER; 
                    mListNavLayout.addView(mSpinner, params); 
                } 
                if (mSpinner.getAdapter() != mSpinnerAdapter) { 
                    mSpinner.setAdapter(mSpinnerAdapter); 
                } 
                mSpinner.setOnItemSelectedListener(mNavItemSelectedListener); 
                addView(mListNavLayout); 
                break
            case ActionBar.NAVIGATION_MODE_TABS: 
                if (mTabScrollView != null && mIncludeTabs) { 
                    addView(mTabScrollView); 
                } 
                break
            } 
            mNavigationMode = mode; 
            requestLayout(); 
        } 
    } 
 
    public void setDropdownAdapter(SpinnerAdapter adapter) { 
        mSpinnerAdapter = adapter; 
        if (mSpinner != null) { 
            mSpinner.setAdapter(adapter); 
        } 
    } 
 
    public SpinnerAdapter getDropdownAdapter() { 
        return mSpinnerAdapter; 
    } 
 
    public void setDropdownSelectedPosition(int position) { 
        mSpinner.setSelection(position); 
    } 
 
    public int getDropdownSelectedPosition() { 
        return mSpinner.getSelectedItemPosition(); 
    } 
 
    public View getCustomNavigationView() { 
        return mCustomNavView; 
    } 
 
    public int getNavigationMode() { 
        return mNavigationMode; 
    } 
 
    public int getDisplayOptions() { 
        return mDisplayOptions; 
    } 
 
    @Override 
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() { 
        // Used by custom nav views if they don't supply layout params. Everything else 
        // added to an ActionBarView should have them already. 
        return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY); 
    } 
 
    @Override 
    protected void onFinishInflate() { 
        super.onFinishInflate(); 
 
        addView(mHomeLayout); 
 
        if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { 
            final ViewParent parent = mCustomNavView.getParent(); 
            if (parent != this) { 
                if (parent instanceof ViewGroup) { 
                    ((ViewGroup) parent).removeView(mCustomNavView); 
                } 
                addView(mCustomNavView); 
            } 
        } 
    } 
 
    private void initTitle() { 
        if (mTitleLayout == null) { 
            LayoutInflater inflater = LayoutInflater.from(getContext()); 
            mTitleLayout = (LinearLayout) inflater.inflate(R.layout.abs__action_bar_title_item, 
                    thisfalse); 
            mTitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_title); 
            mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.abs__action_bar_subtitle); 
            mTitleUpView = mTitleLayout.findViewById(R.id.abs__up); 
 
            mTitleLayout.setOnClickListener(mUpClickListener); 
 
            if (mTitleStyleRes != 0) { 
                mTitleView.setTextAppearance(mContext, mTitleStyleRes); 
            } 
            if (mTitle != null) { 
                mTitleView.setText(mTitle); 
            } 
 
            if (mSubtitleStyleRes != 0) { 
                mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); 
            } 
            if (mSubtitle != null) { 
                mSubtitleView.setText(mSubtitle); 
                mSubtitleView.setVisibility(VISIBLE); 
            } 
 
            final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0
            final boolean showHome = (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0
            mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE); 
            mTitleLayout.setEnabled(homeAsUp && !showHome); 
        } 
 
        addView(mTitleLayout); 
        if (mExpandedActionView != null || 
                (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) { 
            // Don't show while in expanded mode or with empty text 
            mTitleLayout.setVisibility(GONE); 
        } 
    } 
 
    public void setContextView(ActionBarContextView view) { 
        mContextView = view; 
    } 
 
    public void setCollapsable(boolean collapsable) { 
        mIsCollapsable = collapsable; 
    } 
 
    public boolean isCollapsed() { 
        return mIsCollapsed; 
    } 
 
    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
        final int childCount = getChildCount(); 
        if (mIsCollapsable) { 
            int visibleChildren = 0
            for (int i = 0; i < childCount; i++) { 
                final View child = getChildAt(i); 
                if (child.getVisibility() != GONE && 
                        !(child == mMenuView && mMenuView.getChildCount() == 0)) { 
                    visibleChildren++; 
                } 
            } 
 
            if (visibleChildren == 0) { 
                // No size for an empty action bar when collapsable. 
                setMeasuredDimension(00); 
                mIsCollapsed = true
                return
            } 
        } 
        mIsCollapsed = false
 
        int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
        if (widthMode != MeasureSpec.EXACTLY) { 
            throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + 
                    "with android:layout_width=\"match_parent\" (or fill_parent)"); 
        } 
 
        int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
        if (heightMode != MeasureSpec.AT_MOST) { 
            throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + 
                    "with android:layout_height=\"wrap_content\""); 
        } 
 
        int contentWidth = MeasureSpec.getSize(widthMeasureSpec); 
 
        int maxHeight = mContentHeight > 0 ? 
                mContentHeight : MeasureSpec.getSize(heightMeasureSpec); 
 
        final int verticalPadding = getPaddingTop() + getPaddingBottom(); 
        final int paddingLeft = getPaddingLeft(); 
        final int paddingRight = getPaddingRight(); 
        final int height = maxHeight - verticalPadding; 
        final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); 
 
        int availableWidth = contentWidth - paddingLeft - paddingRight; 
        int leftOfCenter = availableWidth / 2
        int rightOfCenter = leftOfCenter; 
 
        HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; 
 
        if (homeLayout.getVisibility() != GONE) { 
            final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams(); 
            int homeWidthSpec; 
            if (lp.width < 0) { 
                homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST); 
            } else { 
                homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); 
            } 
            homeLayout.measure(homeWidthSpec, 
                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 
            final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getLeftOffset(); 
            availableWidth = Math.max(0, availableWidth - homeWidth); 
            leftOfCenter = Math.max(0, availableWidth - homeWidth); 
        } 
 
        if (mMenuView != null && mMenuView.getParent() == this) { 
            availableWidth = measureChildView(mMenuView, availableWidth, 
                    childSpecHeight, 0); 
            rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth()); 
        } 
 
        if (mIndeterminateProgressView != null && 
                mIndeterminateProgressView.getVisibility() != GONE) { 
            availableWidth = measureChildView(mIndeterminateProgressView, availableWidth, 
                    childSpecHeight, 0); 
            rightOfCenter = Math.max(0
                    rightOfCenter - mIndeterminateProgressView.getMeasuredWidth()); 
        } 
 
        final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && 
                (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0
 
        if (mExpandedActionView == null) { 
            switch (mNavigationMode) { 
                case ActionBar.NAVIGATION_MODE_LIST: 
                    if (mListNavLayout != null) { 
                        final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; 
                        availableWidth = Math.max(0, availableWidth - itemPaddingSize); 
                        leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); 
                        mListNavLayout.measure( 
                                MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), 
                                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 
                        final int listNavWidth = mListNavLayout.getMeasuredWidth(); 
                        availableWidth = Math.max(0, availableWidth - listNavWidth); 
                        leftOfCenter = Math.max(0, leftOfCenter - listNavWidth); 
                    } 
                    break
                case ActionBar.NAVIGATION_MODE_TABS: 
                    if (mTabScrollView != null) { 
                        final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding; 
                        availableWidth = Math.max(0, availableWidth - itemPaddingSize); 
                        leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize); 
                        mTabScrollView.measure( 
                                MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), 
                                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 
                        final int tabWidth = mTabScrollView.getMeasuredWidth(); 
                        availableWidth = Math.max(0, availableWidth - tabWidth); 
                        leftOfCenter = Math.max(0, leftOfCenter - tabWidth); 
                    } 
                    break
            } 
        } 
 
        View customView = null
        if (mExpandedActionView != null) { 
            customView = mExpandedActionView; 
        } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && 
                mCustomNavView != null) { 
            customView = mCustomNavView; 
        } 
 
        if (customView != null) { 
            final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams()); 
            final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? 
                    (ActionBar.LayoutParams) lp : null
 
            int horizontalMargin = 0
            int verticalMargin = 0
            if (ablp != null) { 
                horizontalMargin = ablp.leftMargin + ablp.rightMargin; 
                verticalMargin = ablp.topMargin + ablp.bottomMargin; 
            } 
 
            // If the action bar is wrapping to its content height, don't allow a custom 
            // view to MATCH_PARENT. 
            int customNavHeightMode; 
            if (mContentHeight <= 0) { 
                customNavHeightMode = MeasureSpec.AT_MOST; 
            } else { 
                customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ? 
                        MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; 
            } 
            final int customNavHeight = Math.max(0
                    (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin); 
 
            final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ? 
                    MeasureSpec.EXACTLY : MeasureSpec.AT_MOST; 
            int customNavWidth = Math.max(0
                    (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth) 
                    - horizontalMargin); 
            final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) & 
                    Gravity.HORIZONTAL_GRAVITY_MASK; 
 
            // Centering a custom view is treated specially; we try to center within the whole 
            // action bar rather than in the available space. 
            if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) { 
                customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2
            } 
 
            customView.measure( 
                    MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode), 
                    MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode)); 
            availableWidth -= horizontalMargin + customView.getMeasuredWidth(); 
        } 
 
        if (mExpandedActionView == null && showTitle) { 
            availableWidth = measureChildView(mTitleLayout, availableWidth, 
                    MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0); 
            leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth()); 
        } 
 
        if (mContentHeight <= 0) { 
            int measuredHeight = 0
            for (int i = 0; i < childCount; i++) { 
                View v = getChildAt(i); 
                int paddedViewHeight = v.getMeasuredHeight() + verticalPadding; 
                if (paddedViewHeight > measuredHeight) { 
                    measuredHeight = paddedViewHeight; 
                } 
            } 
            setMeasuredDimension(contentWidth, measuredHeight); 
        } else { 
            setMeasuredDimension(contentWidth, maxHeight); 
        } 
 
        if (mContextView != null) { 
            mContextView.setContentHeight(getMeasuredHeight()); 
        } 
 
        if (mProgressView != null && mProgressView.getVisibility() != GONE) { 
            mProgressView.measure(MeasureSpec.makeMeasureSpec( 
                    contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY), 
                    MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST)); 
        } 
    } 
 
    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
        int x = getPaddingLeft(); 
        final int y = getPaddingTop(); 
        final int contentHeight = b - t - getPaddingTop() - getPaddingBottom(); 
 
        if (contentHeight <= 0) { 
            // Nothing to do if we can't see anything. 
            return
        } 
 
        HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; 
        if (homeLayout.getVisibility() != GONE) { 
            final int leftOffset = homeLayout.getLeftOffset(); 
            x += positionChild(homeLayout, x + leftOffset, y, contentHeight) + leftOffset; 
        } 
 
        if (mExpandedActionView == null) { 
            final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && 
                    (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0
            if (showTitle) { 
                x += positionChild(mTitleLayout, x, y, contentHeight); 
            } 
 
            switch (mNavigationMode) { 
                case ActionBar.NAVIGATION_MODE_STANDARD: 
                    break
                case ActionBar.NAVIGATION_MODE_LIST: 
                    if (mListNavLayout != null) { 
                        if (showTitle) x += mItemPadding; 
                        x += positionChild(mListNavLayout, x, y, contentHeight) + mItemPadding; 
                    } 
                    break
                case ActionBar.NAVIGATION_MODE_TABS: 
                    if (mTabScrollView != null) { 
                        if (showTitle) x += mItemPadding; 
                        x += positionChild(mTabScrollView, x, y, contentHeight) + mItemPadding; 
                    } 
                    break
            } 
        } 
 
        int menuLeft = r - l - getPaddingRight(); 
        if (mMenuView != null && mMenuView.getParent() == this) { 
            positionChildInverse(mMenuView, menuLeft, y, contentHeight); 
            menuLeft -= mMenuView.getMeasuredWidth(); 
        } 
 
        if (mIndeterminateProgressView != null && 
                mIndeterminateProgressView.getVisibility() != GONE) { 
            positionChildInverse(mIndeterminateProgressView, menuLeft, y, contentHeight); 
            menuLeft -= mIndeterminateProgressView.getMeasuredWidth(); 
        } 
 
        View customView = null
        if (mExpandedActionView != null) { 
            customView = mExpandedActionView; 
        } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && 
                mCustomNavView != null) { 
            customView = mCustomNavView; 
        } 
        if (customView != null) { 
            ViewGroup.LayoutParams lp = customView.getLayoutParams(); 
            final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? 
                    (ActionBar.LayoutParams) lp : null
 
            final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY; 
            final int navWidth = customView.getMeasuredWidth(); 
 
            int topMargin = 0
            int bottomMargin = 0
            if (ablp != null) { 
                x += ablp.leftMargin; 
                menuLeft -= ablp.rightMargin; 
                topMargin = ablp.topMargin; 
                bottomMargin = ablp.bottomMargin; 
            } 
 
            int hgravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK; 
            // See if we actually have room to truly center; if not push against left or right. 
            if (hgravity == Gravity.CENTER_HORIZONTAL) { 
                final int centeredLeft = ((getRight() - getLeft()) - navWidth) / 2
                if (centeredLeft < x) { 
                    hgravity = Gravity.LEFT; 
                } else if (centeredLeft + navWidth > menuLeft) { 
                    hgravity = Gravity.RIGHT; 
                } 
            } else if (gravity == -1) { 
                hgravity = Gravity.LEFT; 
            } 
 
            int xpos = 0
            switch (hgravity) { 
                case Gravity.CENTER_HORIZONTAL: 
                    xpos = ((getRight() - getLeft()) - navWidth) / 2
                    break
                case Gravity.LEFT: 
                    xpos = x; 
                    break
                case Gravity.RIGHT: 
                    xpos = menuLeft - navWidth; 
                    break
            } 
 
            int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; 
 
            if (gravity == -1) { 
                vgravity = Gravity.CENTER_VERTICAL; 
            } 
 
            int ypos = 0
            switch (vgravity) { 
                case Gravity.CENTER_VERTICAL: 
                    final int paddedTop = getPaddingTop(); 
                    final int paddedBottom = getBottom() - getTop() - getPaddingBottom(); 
                    ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2
                    break
                case Gravity.TOP: 
                    ypos = getPaddingTop() + topMargin; 
                    break
                case Gravity.BOTTOM: 
                    ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight() 
                            - bottomMargin; 
                    break
            } 
            final int customWidth = customView.getMeasuredWidth(); 
            customView.layout(xpos, ypos, xpos + customWidth, 
                    ypos + customView.getMeasuredHeight()); 
            x += customWidth; 
        } 
 
        if (mProgressView != null) { 
            mProgressView.bringToFront(); 
            final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2
            mProgressView.layout(mProgressBarPadding, -halfProgressHeight, 
                    mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight); 
        } 
    } 
 
    @Override 
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { 
        return new ActionBar.LayoutParams(getContext(), attrs); 
    } 
 
    @Override 
    public ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) { 
        if (lp == null) { 
            lp = generateDefaultLayoutParams(); 
        } 
        return lp; 
    } 
 
    @Override 
    public Parcelable onSaveInstanceState() { 
        Parcelable superState = super.onSaveInstanceState(); 
        SavedState state = new SavedState(superState); 
 
        if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) { 
            state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId(); 
        } 
 
        state.isOverflowOpen = isOverflowMenuShowing(); 
 
        return state; 
    } 
 
    @Override 
    public void onRestoreInstanceState(Parcelable p) { 
        SavedState state = (SavedState) p; 
 
        super.onRestoreInstanceState(state.getSuperState()); 
 
        if (state.expandedMenuItemId != 0 && 
                mExpandedMenuPresenter != null && mOptionsMenu != null) { 
            final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId); 
            if (item != null) { 
                item.expandActionView(); 
            } 
        } 
 
        if (state.isOverflowOpen) { 
            postShowOverflowMenu(); 
        } 
    } 
 
    static class SavedState extends BaseSavedState { 
        int expandedMenuItemId; 
        boolean isOverflowOpen; 
 
        SavedState(Parcelable superState) { 
            super(superState); 
        } 
 
        private SavedState(Parcel in) { 
            super(in); 
            expandedMenuItemId = in.readInt(); 
            isOverflowOpen = in.readInt() != 0
        } 
 
        @Override 
        public void writeToParcel(Parcel out, int flags) { 
            super.writeToParcel(out, flags); 
            out.writeInt(expandedMenuItemId); 
            out.writeInt(isOverflowOpen ? 1 : 0); 
        } 
 
        public static final Parcelable.Creator<SavedState> CREATOR = 
                new Parcelable.Creator<SavedState>() { 
            public SavedState createFromParcel(Parcel in) { 
                return new SavedState(in); 
            } 
 
            public SavedState[] newArray(int size) { 
                return new SavedState[size]; 
            } 
        }; 
    } 
 
    public static class HomeView extends FrameLayout { 
        private View mUpView; 
        private ImageView mIconView; 
        private int mUpWidth; 
 
        public HomeView(Context context) { 
            this(context, null); 
        } 
 
        public HomeView(Context context, AttributeSet attrs) { 
            super(context, attrs); 
        } 
 
        public void setUp(boolean isUp) { 
            mUpView.setVisibility(isUp ? VISIBLE : GONE); 
        } 
 
        public void setIcon(Drawable icon) { 
            mIconView.setImageDrawable(icon); 
        } 
 
        @Override 
        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 
            onPopulateAccessibilityEvent(event); 
            return true
        } 
 
        @Override 
        public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
                super.onPopulateAccessibilityEvent(event); 
            } 
            final CharSequence cdesc = getContentDescription(); 
            if (!TextUtils.isEmpty(cdesc)) { 
                event.getText().add(cdesc); 
            } 
        } 
 
        @Override 
        public boolean dispatchHoverEvent(MotionEvent event) { 
            // Don't allow children to hover; we want this to be treated as a single component. 
            return onHoverEvent(event); 
        } 
 
        @Override 
        protected void onFinishInflate() { 
            mUpView = findViewById(R.id.abs__up); 
            mIconView = (ImageView) findViewById(R.id.abs__home); 
        } 
 
        public int getLeftOffset() { 
            return mUpView.getVisibility() == GONE ? mUpWidth : 0
        } 
 
        @Override 
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
            measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0); 
            final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); 
            mUpWidth = upLp.leftMargin + mUpView.getMeasuredWidth() + upLp.rightMargin; 
            int width = mUpView.getVisibility() == GONE ? 0 : mUpWidth; 
            int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin; 
            measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0); 
            final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); 
            width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin; 
            height = Math.max(height, 
                    iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin); 
 
            final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
            final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
            final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 
            final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 
 
            switch (widthMode) { 
                case MeasureSpec.AT_MOST: 
                    width = Math.min(width, widthSize); 
                    break
                case MeasureSpec.EXACTLY: 
                    width = widthSize; 
                    break
                case MeasureSpec.UNSPECIFIED: 
                default
                    break
            } 
            switch (heightMode) { 
                case MeasureSpec.AT_MOST: 
                    height = Math.min(height, heightSize); 
                    break
                case MeasureSpec.EXACTLY: 
                    height = heightSize; 
                    break
                case MeasureSpec.UNSPECIFIED: 
                default
                    break
            } 
            setMeasuredDimension(width, height); 
        } 
 
        @Override 
        protected void onLayout(boolean changed, int l, int t, int r, int b) { 
            final int vCenter = (b - t) / 2
            //UNUSED int width = r - l; 
            int upOffset = 0
            if (mUpView.getVisibility() != GONE) { 
                final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams(); 
                final int upHeight = mUpView.getMeasuredHeight(); 
                final int upWidth = mUpView.getMeasuredWidth(); 
                final int upTop = vCenter - upHeight / 2
                mUpView.layout(0, upTop, upWidth, upTop + upHeight); 
                upOffset = upLp.leftMargin + upWidth + upLp.rightMargin; 
                //UNUSED width -= upOffset; 
                l += upOffset; 
            } 
            final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams(); 
            final int iconHeight = mIconView.getMeasuredHeight(); 
            final int iconWidth = mIconView.getMeasuredWidth(); 
            final int hCenter = (r - l) / 2
            final int iconLeft = upOffset + Math.max(iconLp.leftMargin, hCenter - iconWidth / 2); 
            final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2); 
            mIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight); 
        } 
    } 
 
    private class ExpandedActionViewMenuPresenter implements MenuPresenter { 
        MenuBuilder mMenu; 
        MenuItemImpl mCurrentExpandedItem; 
 
        @Override 
        public void initForMenu(Context context, MenuBuilder menu) { 
            // Clear the expanded action view when menus change. 
            if (mMenu != null && mCurrentExpandedItem != null) { 
                mMenu.collapseItemActionView(mCurrentExpandedItem); 
            } 
            mMenu = menu; 
        } 
 
        @Override 
        public MenuView getMenuView(ViewGroup root) { 
            return null
        } 
 
        @Override 
        public void updateMenuView(boolean cleared) { 
            // Make sure the expanded item we have is still there. 
            if (mCurrentExpandedItem != null) { 
                boolean found = false
 
                if (mMenu != null) { 
                    final int count = mMenu.size(); 
                    for (int i = 0; i < count; i++) { 
                        final MenuItem item = mMenu.getItem(i); 
                        if (item == mCurrentExpandedItem) { 
                            found = true
                            break
                        } 
                    } 
                } 
 
                if (!found) { 
                    // The item we had expanded disappeared. Collapse. 
                    collapseItemActionView(mMenu, mCurrentExpandedItem); 
                } 
            } 
        } 
 
        @Override 
        public void setCallback(Callback cb) { 
        } 
 
        @Override 
        public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 
            return false
        } 
 
        @Override 
        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 
        } 
 
        @Override 
        public boolean flagActionItems() { 
            return false
        } 
 
        @Override 
        public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { 
            mExpandedActionView = item.getActionView(); 
            mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(/* TODO getResources() */)); 
            mCurrentExpandedItem = item; 
            if (mExpandedActionView.getParent() != ActionBarView.this) { 
                addView(mExpandedActionView); 
            } 
            if (mExpandedHomeLayout.getParent() != ActionBarView.this) { 
                addView(mExpandedHomeLayout); 
            } 
            mHomeLayout.setVisibility(GONE); 
            if (mTitleLayout != null) mTitleLayout.setVisibility(GONE); 
            if (mTabScrollView != null) mTabScrollView.setVisibility(GONE); 
            if (mSpinner != null) mSpinner.setVisibility(GONE); 
            if (mCustomNavView != null) mCustomNavView.setVisibility(GONE); 
            requestLayout(); 
            item.setActionViewExpanded(true); 
 
            if (mExpandedActionView instanceof CollapsibleActionView) { 
                ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded(); 
            } 
 
            return true
        } 
 
        @Override 
        public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { 
            // Do this before detaching the actionview from the hierarchy, in case 
            // it needs to dismiss the soft keyboard, etc. 
            if (mExpandedActionView instanceof CollapsibleActionView) { 
                ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed(); 
            } 
 
            removeView(mExpandedActionView); 
            removeView(mExpandedHomeLayout); 
            mExpandedActionView = null
            if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) { 
                mHomeLayout.setVisibility(VISIBLE); 
            } 
            if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { 
                if (mTitleLayout == null) { 
                    initTitle(); 
                } else { 
                    mTitleLayout.setVisibility(VISIBLE); 
                } 
            } 
            if (mTabScrollView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { 
                mTabScrollView.setVisibility(VISIBLE); 
            } 
            if (mSpinner != null && mNavigationMode == ActionBar.NAVIGATION_MODE_LIST) { 
                mSpinner.setVisibility(VISIBLE); 
            } 
            if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { 
                mCustomNavView.setVisibility(VISIBLE); 
            } 
            mExpandedHomeLayout.setIcon(null); 
            mCurrentExpandedItem = null
            requestLayout(); 
            item.setActionViewExpanded(false); 
 
            return true
        } 
 
        @Override 
        public int getId() { 
            return 0
        } 
 
        @Override 
        public Parcelable onSaveInstanceState() { 
            return null
        } 
 
        @Override 
        public void onRestoreInstanceState(Parcelable state) { 
        } 
    } 
}