From 8d02deabac62c4a68a335a7b3141795466362b89 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Tue, 31 May 2011 21:35:13 -0700 Subject: [PATCH] Implement bug 4500971 - Collapsable action views Action views may now be flagged as 'collapsable'. This means that the action menu will always show them in the collapsed state by default. When selected, the action view will "take over" the navigation/view side of an action bar until dismissed via the home/up button. This feature allows for more long-term exclusive modes akin to ActionModes but less intrusive. The action menu itself remains unaffected. Collapsable action views are ideal for things such as search or categories of tool palettes. Change-Id: Ibafce5631befbfe67c5d834c2e2617d3d7f6da7a --- api/current.txt | 11 + core/java/android/view/MenuItem.java | 104 +++++ .../internal/view/menu/ActionMenuItem.java | 27 ++ .../view/menu/ActionMenuPresenter.java | 11 +- .../internal/view/menu/BaseMenuPresenter.java | 8 + .../internal/view/menu/ListMenuPresenter.java | 8 + .../internal/view/menu/MenuBuilder.java | 45 +- .../internal/view/menu/MenuItemImpl.java | 59 +++ .../internal/view/menu/MenuPopupHelper.java | 8 + .../internal/view/menu/MenuPresenter.java | 18 + .../internal/view/menu/SubMenuBuilder.java | 10 + .../internal/widget/AbsActionBarView.java | 20 +- .../internal/widget/ActionBarContextView.java | 22 +- .../internal/widget/ActionBarView.java | 411 ++++++++++++++---- core/res/res/values/attrs.xml | 4 + .../internal/policy/impl/PhoneWindow.java | 10 +- 16 files changed, 657 insertions(+), 119 deletions(-) diff --git a/api/current.txt b/api/current.txt index 9e87e9c5235f7..bf52ce8b8ffc0 100644 --- a/api/current.txt +++ b/api/current.txt @@ -20970,6 +20970,8 @@ package android.view { } public abstract interface MenuItem { + method public abstract boolean collapseActionView(); + method public abstract boolean expandActionView(); method public abstract android.view.View getActionView(); method public abstract char getAlphabeticShortcut(); method public abstract int getGroupId(); @@ -20983,6 +20985,7 @@ package android.view { method public abstract java.lang.CharSequence getTitle(); method public abstract java.lang.CharSequence getTitleCondensed(); method public abstract boolean hasSubMenu(); + method public abstract boolean isActionViewExpanded(); method public abstract boolean isCheckable(); method public abstract boolean isChecked(); method public abstract boolean isEnabled(); @@ -20997,19 +21000,27 @@ package android.view { method public abstract android.view.MenuItem setIcon(int); method public abstract android.view.MenuItem setIntent(android.content.Intent); method public abstract android.view.MenuItem setNumericShortcut(char); + method public abstract android.view.MenuItem setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener); method public abstract android.view.MenuItem setOnMenuItemClickListener(android.view.MenuItem.OnMenuItemClickListener); method public abstract android.view.MenuItem setShortcut(char, char); method public abstract void setShowAsAction(int); + method public abstract android.view.MenuItem setShowAsActionFlags(int); method public abstract android.view.MenuItem setTitle(java.lang.CharSequence); method public abstract android.view.MenuItem setTitle(int); method public abstract android.view.MenuItem setTitleCondensed(java.lang.CharSequence); method public abstract android.view.MenuItem setVisible(boolean); field public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2 + field public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8 field public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1 field public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0 field public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4 } + public static abstract interface MenuItem.OnActionExpandListener { + method public abstract boolean onMenuItemActionCollapse(android.view.MenuItem); + method public abstract boolean onMenuItemActionExpand(android.view.MenuItem); + } + public static abstract interface MenuItem.OnMenuItemClickListener { method public abstract boolean onMenuItemClick(android.view.MenuItem); } diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java index 780c52ed6440e..dc6826411a428 100644 --- a/core/java/android/view/MenuItem.java +++ b/core/java/android/view/MenuItem.java @@ -51,6 +51,13 @@ public interface MenuItem { * it also has an icon specified. */ public static final int SHOW_AS_ACTION_WITH_TEXT = 4; + + /** + * This item's action view collapses to a normal menu item. + * When expanded, the action view temporarily takes over + * a larger segment of its container. + */ + public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; /** * Interface definition for a callback to be invoked when a menu item is @@ -73,6 +80,34 @@ public interface MenuItem { public boolean onMenuItemClick(MenuItem item); } + /** + * Interface definition for a callback to be invoked when a menu item + * marked with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} is + * expanded or collapsed. + * + * @see MenuItem#expandActionView() + * @see MenuItem#collapseActionView() + * @see MenuItem#setShowAsActionFlags(int) + * @see MenuItem# + */ + public interface OnActionExpandListener { + /** + * Called when a menu item with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} + * is expanded. + * @param item Item that was expanded + * @return true if the item should expand, false if expansion should be suppressed. + */ + public boolean onMenuItemActionExpand(MenuItem item); + + /** + * Called when a menu item with {@link MenuItem#SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW} + * is collapsed. + * @param item Item that was collapsed + * @return true if the item should collapse, false if collapsing should be suppressed. + */ + public boolean onMenuItemActionCollapse(MenuItem item); + } + /** * Return the identifier for this menu item. The identifier can not * be changed after the menu is created. @@ -420,6 +455,27 @@ public interface MenuItem { */ public void setShowAsAction(int actionEnum); + /** + * Sets how this item should display in the presence of an Action Bar. + * The parameter actionEnum is a flag set. One of {@link #SHOW_AS_ACTION_ALWAYS}, + * {@link #SHOW_AS_ACTION_IF_ROOM}, or {@link #SHOW_AS_ACTION_NEVER} should + * be used, and you may optionally OR the value with {@link #SHOW_AS_ACTION_WITH_TEXT}. + * SHOW_AS_ACTION_WITH_TEXT requests that when the item is shown as an action, + * it should be shown with a text label. + * + *

Note: This method differs from {@link #setShowAsAction(int)} only in that it + * returns the current MenuItem instance for call chaining. + * + * @param actionEnum How the item should display. One of + * {@link #SHOW_AS_ACTION_ALWAYS}, {@link #SHOW_AS_ACTION_IF_ROOM}, or + * {@link #SHOW_AS_ACTION_NEVER}. SHOW_AS_ACTION_NEVER is the default. + * + * @see android.app.ActionBar + * @see #setActionView(View) + * @return This MenuItem instance for call chaining. + */ + public MenuItem setShowAsActionFlags(int actionEnum); + /** * Set an action view for this menu item. An action view will be displayed in place * of an automatically generated menu item element in the UI when this item is shown @@ -453,4 +509,52 @@ public interface MenuItem { * @see #setShowAsAction(int) */ public View getActionView(); + + /** + * Expand the action view associated with this menu item. + * The menu item must have an action view set, as well as + * the showAsAction flag {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. + * If a listener has been set using {@link #setOnActionExpandListener(OnActionExpandListener)} + * it will have its {@link OnActionExpandListener#onMenuItemActionExpand(MenuItem)} + * method invoked. The listener may return false from this method to prevent expanding + * the action view. + * + * @return true if the action view was expanded, false otherwise. + */ + public boolean expandActionView(); + + /** + * Collapse the action view associated with this menu item. + * The menu item must have an action view set, as well as the showAsAction flag + * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. If a listener has been set using + * {@link #setOnActionExpandListener(OnActionExpandListener)} it will have its + * {@link OnActionExpandListener#onMenuItemActionCollapse(MenuItem)} method invoked. + * The listener may return false from this method to prevent collapsing the action view. + * + * @return true if the action view was collapsed, false otherwise. + */ + public boolean collapseActionView(); + + /** + * Returns true if this menu item's action view has been expanded. + * + * @return true if the item's action view is expanded, false otherwise. + * + * @see #expandActionView() + * @see #collapseActionView() + * @see #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW + * @see OnActionExpandListener + */ + public boolean isActionViewExpanded(); + + /** + * Set an {@link OnActionExpandListener} on this menu item to be notified when + * the associated action view is expanded or collapsed. The menu item must + * be configured to expand or collapse its action view using the flag + * {@link #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW}. + * + * @param listener Listener that will respond to expand/collapse events + * @return This menu item instance for call chaining + */ + public MenuItem setOnActionExpandListener(OnActionExpandListener listener); } \ No newline at end of file diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java index 0ef4861e94763..a4bcf6081de54 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItem.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java @@ -236,4 +236,31 @@ public class ActionMenuItem implements MenuItem { public MenuItem setActionView(int resId) { throw new UnsupportedOperationException(); } + + @Override + public MenuItem setShowAsActionFlags(int actionEnum) { + setShowAsAction(actionEnum); + return this; + } + + @Override + public boolean expandActionView() { + return false; + } + + @Override + public boolean collapseActionView() { + return false; + } + + @Override + public boolean isActionViewExpanded() { + return false; + } + + @Override + public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { + // No need to save the listener; ActionMenuItem does not support collapsing items. + return this; + } } diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java index 0051ec3a1b44a..91dd7e36f7ba3 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java @@ -112,8 +112,11 @@ public class ActionMenuPresenter extends BaseMenuPresenter { @Override public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) { - final View actionView = item.getActionView(); - return actionView != null ? actionView : super.getItemView(item, convertView, parent); + View actionView = item.getActionView(); + actionView = actionView != null && !item.hasCollapsibleActionView() ? + actionView : super.getItemView(item, convertView, parent); + actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE); + return actionView; } @Override @@ -303,7 +306,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter { if (item.requiresActionButton()) { View v = item.getActionView(); - if (v == null) { + if (v == null || item.hasCollapsibleActionView()) { v = getItemView(item, mScrapActionButtonView, parent); if (mScrapActionButtonView == null) { mScrapActionButtonView = v; @@ -329,7 +332,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter { if (isAction) { View v = item.getActionView(); - if (v == null) { + if (v == null || item.hasCollapsibleActionView()) { v = getItemView(item, mScrapActionButtonView, parent); if (mScrapActionButtonView == null) { mScrapActionButtonView = v; diff --git a/core/java/com/android/internal/view/menu/BaseMenuPresenter.java b/core/java/com/android/internal/view/menu/BaseMenuPresenter.java index 16f51fd20ae05..ddbb08c01e687 100644 --- a/core/java/com/android/internal/view/menu/BaseMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/BaseMenuPresenter.java @@ -192,4 +192,12 @@ public abstract class BaseMenuPresenter implements MenuPresenter { public boolean flagActionItems() { return false; } + + public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } + + public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } } diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java index 2cb2a100c0113..f8d24a34fb9a4 100644 --- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java @@ -159,6 +159,14 @@ public class ListMenuPresenter implements MenuPresenter, AdapterView.OnItemClick return false; } + public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } + + public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } + public void saveHierarchyState(Bundle outState) { SparseArray viewStates = new SparseArray(); if (mMenuView != null) { diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java index e9fcb23113c6b..fdfa9546a040e 100644 --- a/core/java/com/android/internal/view/menu/MenuBuilder.java +++ b/core/java/com/android/internal/view/menu/MenuBuilder.java @@ -744,11 +744,14 @@ public class MenuBuilder implements Menu { if (itemImpl == null || !itemImpl.isEnabled()) { return false; - } + } boolean invoked = itemImpl.invoke(); - if (item.hasSubMenu()) { + if (itemImpl.hasCollapsibleActionView()) { + invoked |= itemImpl.expandActionView(); + if (invoked) close(true); + } else if (item.hasSubMenu()) { close(false); invoked |= dispatchSubMenuSelected((SubMenuBuilder) item.getSubMenu()); @@ -1081,4 +1084,42 @@ public class MenuBuilder implements Menu { boolean getOptionalIconsVisible() { return mOptionalIconsVisible; } + + public boolean expandItemActionView(MenuItemImpl item) { + if (mPresenters.isEmpty()) return false; + + boolean expanded = false; + + stopDispatchingItemsChanged(); + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else if ((expanded = presenter.expandItemActionView(this, item))) { + break; + } + } + startDispatchingItemsChanged(); + + return expanded; + } + + public boolean collapseItemActionView(MenuItemImpl item) { + if (mPresenters.isEmpty()) return false; + + boolean collapsed = false; + + stopDispatchingItemsChanged(); + for (WeakReference ref : mPresenters) { + final MenuPresenter presenter = ref.get(); + if (presenter == null) { + mPresenters.remove(ref); + } else if ((collapsed = presenter.collapseItemActionView(this, item))) { + break; + } + } + startDispatchingItemsChanged(); + + return collapsed; + } } diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java index c6d386d1fa481..f2430e4cb2ead 100644 --- a/core/java/com/android/internal/view/menu/MenuItemImpl.java +++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java @@ -77,6 +77,8 @@ public final class MenuItemImpl implements MenuItem { private int mShowAsAction = SHOW_AS_ACTION_NEVER; private View mActionView; + private OnActionExpandListener mOnActionExpandListener; + private boolean mIsActionViewExpanded = false; /** Used for the icon resource ID if this item does not have an icon */ static final int NO_ICON = 0; @@ -561,4 +563,61 @@ public final class MenuItemImpl implements MenuItem { public View getActionView() { return mActionView; } + + @Override + public MenuItem setShowAsActionFlags(int actionEnum) { + setShowAsAction(actionEnum); + return this; + } + + @Override + public boolean expandActionView() { + if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) == 0 || mActionView == null) { + return false; + } + + if (mOnActionExpandListener == null || + mOnActionExpandListener.onMenuItemActionExpand(this)) { + return mMenu.expandItemActionView(this); + } + + return false; + } + + @Override + public boolean collapseActionView() { + if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) == 0) { + return false; + } + if (mActionView == null) { + // We're already collapsed if we have no action view. + return true; + } + + if (mOnActionExpandListener == null || + mOnActionExpandListener.onMenuItemActionCollapse(this)) { + return mMenu.collapseItemActionView(this); + } + + return false; + } + + @Override + public MenuItem setOnActionExpandListener(OnActionExpandListener listener) { + mOnActionExpandListener = listener; + return this; + } + + public boolean hasCollapsibleActionView() { + return (mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) != 0 && mActionView != null; + } + + public void setActionViewExpanded(boolean isExpanded) { + mIsActionViewExpanded = isExpanded; + mMenu.onItemsChanged(false); + } + + public boolean isActionViewExpanded() { + return mIsActionViewExpanded; + } } diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java index 38cec29835297..57675199d98ef 100644 --- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java +++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java @@ -250,6 +250,14 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On return false; } + public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } + + public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { + return false; + } + private class MenuAdapter extends BaseAdapter { private MenuBuilder mAdapterMenu; diff --git a/core/java/com/android/internal/view/menu/MenuPresenter.java b/core/java/com/android/internal/view/menu/MenuPresenter.java index 5baf41948b399..bd664489aff70 100644 --- a/core/java/com/android/internal/view/menu/MenuPresenter.java +++ b/core/java/com/android/internal/view/menu/MenuPresenter.java @@ -107,4 +107,22 @@ public interface MenuPresenter { * @return true if this presenter changed the action status of any items. */ public boolean flagActionItems(); + + /** + * Called when a menu item with a collapsable action view should expand its action view. + * + * @param menu Menu containing the item to be expanded + * @param item Item to be expanded + * @return true if this presenter expanded the action view, false otherwise. + */ + public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item); + + /** + * Called when a menu item with a collapsable action view should collapse its action view. + * + * @param menu Menu containing the item to be collapsed + * @param item Item to be collapsed + * @return true if this presenter collapsed the action view, false otherwise. + */ + public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item); } diff --git a/core/java/com/android/internal/view/menu/SubMenuBuilder.java b/core/java/com/android/internal/view/menu/SubMenuBuilder.java index 834041fe98355..fb1cd5e81ef76 100644 --- a/core/java/com/android/internal/view/menu/SubMenuBuilder.java +++ b/core/java/com/android/internal/view/menu/SubMenuBuilder.java @@ -111,4 +111,14 @@ public class SubMenuBuilder extends MenuBuilder implements SubMenu { public SubMenu setHeaderView(View view) { return (SubMenu) super.setHeaderViewInt(view); } + + @Override + public boolean expandItemActionView(MenuItemImpl item) { + return mParentMenu.expandItemActionView(item); + } + + @Override + public boolean collapseItemActionView(MenuItemImpl item) { + return mParentMenu.collapseItemActionView(item); + } } diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java index 788883bc378b6..ccbce3e9587cc 100644 --- a/core/java/com/android/internal/widget/AbsActionBarView.java +++ b/core/java/com/android/internal/widget/AbsActionBarView.java @@ -30,7 +30,7 @@ import android.view.animation.DecelerateInterpolator; public abstract class AbsActionBarView extends ViewGroup { protected ActionMenuView mMenuView; - protected ActionMenuPresenter mMenuPresenter; + protected ActionMenuPresenter mActionMenuPresenter; protected ActionBarContainer mSplitView; protected Animator mVisibilityAnim; @@ -108,8 +108,8 @@ public abstract class AbsActionBarView extends ViewGroup { } public boolean showOverflowMenu() { - if (mMenuPresenter != null) { - return mMenuPresenter.showOverflowMenu(); + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.showOverflowMenu(); } return false; } @@ -123,26 +123,26 @@ public abstract class AbsActionBarView extends ViewGroup { } public boolean hideOverflowMenu() { - if (mMenuPresenter != null) { - return mMenuPresenter.hideOverflowMenu(); + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.hideOverflowMenu(); } return false; } public boolean isOverflowMenuShowing() { - if (mMenuPresenter != null) { - return mMenuPresenter.isOverflowMenuShowing(); + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.isOverflowMenuShowing(); } return false; } public boolean isOverflowReserved() { - return mMenuPresenter != null && mMenuPresenter.isOverflowReserved(); + return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved(); } public void dismissPopupMenus() { - if (mMenuPresenter != null) { - mMenuPresenter.dismissPopupMenus(); + if (mActionMenuPresenter != null) { + mActionMenuPresenter.dismissPopupMenus(); } } diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java index deed1c5e76d53..e4c4989fbe22e 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -167,9 +167,9 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi }); final MenuBuilder menu = (MenuBuilder) mode.getMenu(); - mMenuPresenter = new ActionMenuPresenter(); - menu.addMenuPresenter(mMenuPresenter); - mMenuView = (ActionMenuView) mMenuPresenter.getMenuView(this); + mActionMenuPresenter = new ActionMenuPresenter(); + menu.addMenuPresenter(mActionMenuPresenter); + mMenuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); @@ -178,10 +178,10 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi addView(mMenuView); } else { // Allow full screen width in split mode. - mMenuPresenter.setWidthLimit( + mActionMenuPresenter.setWidthLimit( getContext().getResources().getDisplayMetrics().widthPixels, true); // No limit to the item count; use whatever will fit. - mMenuPresenter.setItemLimit(Integer.MAX_VALUE); + mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); // Span the whole width layoutParams.width = LayoutParams.MATCH_PARENT; mSplitView.addView(mMenuView); @@ -227,24 +227,24 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi @Override public boolean showOverflowMenu() { - if (mMenuPresenter != null) { - return mMenuPresenter.showOverflowMenu(); + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.showOverflowMenu(); } return false; } @Override public boolean hideOverflowMenu() { - if (mMenuPresenter != null) { - return mMenuPresenter.hideOverflowMenu(); + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.hideOverflowMenu(); } return false; } @Override public boolean isOverflowMenuShowing() { - if (mMenuPresenter != null) { - return mMenuPresenter.isOverflowMenuShowing(); + if (mActionMenuPresenter != null) { + return mActionMenuPresenter.isOverflowMenuShowing(); } return false; } diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index b7aac148c3b0c..0cf84d24f3aa6 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -21,7 +21,10 @@ import com.android.internal.view.menu.ActionMenuItem; import com.android.internal.view.menu.ActionMenuPresenter; import com.android.internal.view.menu.ActionMenuView; import com.android.internal.view.menu.MenuBuilder; +import com.android.internal.view.menu.MenuItemImpl; import com.android.internal.view.menu.MenuPresenter; +import com.android.internal.view.menu.MenuView; +import com.android.internal.view.menu.SubMenuBuilder; import android.app.ActionBar; import android.app.ActionBar.OnNavigationListener; @@ -33,21 +36,22 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; +import android.os.Parcel; +import android.os.Parcelable; import android.text.TextUtils; -import android.text.TextUtils.TruncateAt; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; import android.view.Window; import android.widget.AdapterView; import android.widget.FrameLayout; -import android.widget.HorizontalScrollView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; @@ -87,9 +91,8 @@ public class ActionBarView extends AbsActionBarView { private Drawable mIcon; private Drawable mLogo; - private View mHomeLayout; - private View mHomeAsUpView; - private ImageView mIconView; + private HomeView mHomeLayout; + private HomeView mExpandedHomeLayout; private LinearLayout mTitleLayout; private TextView mTitleView; private TextView mSubtitleView; @@ -124,6 +127,9 @@ public class ActionBarView extends AbsActionBarView { private Runnable mTabSelector; + private ExpandedActionViewMenuPresenter mExpandedMenuPresenter; + View mExpandedActionView; + private final AdapterView.OnItemSelectedListener mNavItemSelectedListener = new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView parent, View view, int position, long id) { @@ -136,7 +142,15 @@ public class ActionBarView extends AbsActionBarView { } }; - private OnClickListener mTabClickListener = null; + private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() { + @Override + public void onClick(View v) { + final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem; + if (item != null) { + item.collapseActionView(); + } + } + }; public ActionBarView(Context context, AttributeSet attrs) { super(context, attrs); @@ -187,10 +201,11 @@ public class ActionBarView extends AbsActionBarView { com.android.internal.R.styleable.ActionBar_homeLayout, com.android.internal.R.layout.action_bar_home); - mHomeLayout = inflater.inflate(homeResId, this, false); + mHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); - mHomeAsUpView = mHomeLayout.findViewById(com.android.internal.R.id.up); - mIconView = (ImageView) mHomeLayout.findViewById(com.android.internal.R.id.home); + mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, this, false); + mExpandedHomeLayout.setUp(true); + mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener); mTitleStyleRes = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0); mSubtitleStyleRes = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0); @@ -298,7 +313,8 @@ public class ActionBarView extends AbsActionBarView { if (menu == mOptionsMenu) return; if (mOptionsMenu != null) { - mOptionsMenu.removeMenuPresenter(mMenuPresenter); + mOptionsMenu.removeMenuPresenter(mActionMenuPresenter); + mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter); } MenuBuilder builder = (MenuBuilder) menu; @@ -306,13 +322,15 @@ public class ActionBarView extends AbsActionBarView { if (mMenuView != null) { removeView(mMenuView); } - if (mMenuPresenter == null) { - mMenuPresenter = new ActionMenuPresenter(); - mMenuPresenter.setCallback(cb); + if (mActionMenuPresenter == null) { + mActionMenuPresenter = new ActionMenuPresenter(); + mActionMenuPresenter.setCallback(cb); + mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter(); } - builder.addMenuPresenter(mMenuPresenter); + builder.addMenuPresenter(mActionMenuPresenter); + builder.addMenuPresenter(mExpandedMenuPresenter); - final ActionMenuView menuView = (ActionMenuView) mMenuPresenter.getMenuView(this); + final ActionMenuView menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this); final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); menuView.setLayoutParams(layoutParams); @@ -320,10 +338,10 @@ public class ActionBarView extends AbsActionBarView { addView(menuView); } else { // Allow full screen width in split mode. - mMenuPresenter.setWidthLimit( + mActionMenuPresenter.setWidthLimit( getContext().getResources().getDisplayMetrics().widthPixels, true); // No limit to the item count; use whatever will fit. - mMenuPresenter.setItemLimit(Integer.MAX_VALUE); + mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE); // Span the whole width layoutParams.width = LayoutParams.MATCH_PARENT; if (mSplitView != null) { @@ -411,13 +429,12 @@ public class ActionBarView extends AbsActionBarView { mHomeLayout.setVisibility(vis); if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) { - final boolean isUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0; - mHomeAsUpView.setVisibility(isUp ? VISIBLE : GONE); + mHomeLayout.setUp((options & ActionBar.DISPLAY_HOME_AS_UP) != 0); } if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) { final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0; - mIconView.setImageDrawable(logoVis ? mLogo : mIcon); + mHomeLayout.setIcon(logoVis ? mLogo : mIcon); } if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) { @@ -457,7 +474,7 @@ public class ActionBarView extends AbsActionBarView { mIcon = icon; if (icon != null && ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) { - mIconView.setImageDrawable(icon); + mHomeLayout.setIcon(icon); } } @@ -468,7 +485,7 @@ public class ActionBarView extends AbsActionBarView { public void setLogo(Drawable logo) { mLogo = logo; if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) { - mIconView.setImageDrawable(logo); + mHomeLayout.setIcon(logo); } } @@ -482,7 +499,7 @@ public class ActionBarView extends AbsActionBarView { private int getPreferredIconDensity() { final Resources res = mContext.getResources(); final int availableHeight = getLayoutParams().height - - mIconView.getPaddingTop() - mIconView.getPaddingBottom(); + mHomeLayout.getVerticalIconPadding(); int iconSize = res.getDimensionPixelSize(android.R.dimen.app_icon_size); if (iconSize * DisplayMetrics.DENSITY_LOW >= availableHeight) { @@ -685,10 +702,13 @@ public class ActionBarView extends AbsActionBarView { int leftOfCenter = availableWidth / 2; int rightOfCenter = leftOfCenter; - if (mHomeLayout.getVisibility() != GONE) { - mHomeLayout.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), + View homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; + + if (homeLayout.getVisibility() != GONE) { + homeLayout.measure( + MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - final int homeWidth = mHomeLayout.getMeasuredWidth(); + final int homeWidth = homeLayout.getMeasuredWidth(); availableWidth = Math.max(0, availableWidth - homeWidth); leftOfCenter = Math.max(0, availableWidth - homeWidth); } @@ -699,40 +719,42 @@ public class ActionBarView extends AbsActionBarView { rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth()); } - boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; - if (showTitle) { - availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); - leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth()); - } + if (mExpandedActionView == null) { + boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && + (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; + if (showTitle) { + availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); + leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth()); + } - 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); + 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; } - 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; } if (mIndeterminateProgressView != null && @@ -743,8 +765,16 @@ public class ActionBarView extends AbsActionBarView { rightOfCenter - mIndeterminateProgressView.getMeasuredWidth()); } - if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) { - final LayoutParams lp = generateLayoutParams(mCustomNavView.getLayoutParams()); + View customView = null; + if (mExpandedActionView != null) { + customView = mExpandedActionView; + } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && + mCustomNavView != null) { + customView = mCustomNavView; + } + + if (customView != null) { + final LayoutParams lp = generateLayoutParams(customView.getLayoutParams()); final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ? (ActionBar.LayoutParams) lp : null; @@ -781,7 +811,7 @@ public class ActionBarView extends AbsActionBarView { customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2; } - mCustomNavView.measure( + customView.measure( MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode), MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode)); } @@ -822,31 +852,34 @@ public class ActionBarView extends AbsActionBarView { return; } - if (mHomeLayout.getVisibility() != GONE) { - x += positionChild(mHomeLayout, x, y, contentHeight); - } - - final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; - if (showTitle) { - x += positionChild(mTitleLayout, x, y, contentHeight); + View homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout; + if (homeLayout.getVisibility() != GONE) { + x += positionChild(homeLayout, 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; + 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); } - break; - case ActionBar.NAVIGATION_MODE_TABS: - if (mTabScrollView != null) { - if (showTitle) x += mItemPadding; - x += positionChild(mTabScrollView, x, y, contentHeight) + mItemPadding; + + 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; } - break; } int menuLeft = r - l - getPaddingRight(); @@ -861,13 +894,20 @@ public class ActionBarView extends AbsActionBarView { menuLeft -= mIndeterminateProgressView.getMeasuredWidth(); } - if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) { - LayoutParams lp = mCustomNavView.getLayoutParams(); + View customView = null; + if (mExpandedActionView != null) { + customView = mExpandedActionView; + } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && + mCustomNavView != null) { + customView = mCustomNavView; + } + if (customView != null) { + 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 = mCustomNavView.getMeasuredWidth(); + final int navWidth = customView.getMeasuredWidth(); int topMargin = 0; int bottomMargin = 0; @@ -907,17 +947,17 @@ public class ActionBarView extends AbsActionBarView { case Gravity.CENTER_VERTICAL: final int paddedTop = mTop + getPaddingTop(); final int paddedBottom = mBottom - getPaddingBottom(); - ypos = ((paddedBottom - paddedTop) - mCustomNavView.getMeasuredHeight()) / 2; + ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2; break; case Gravity.TOP: ypos = getPaddingTop() + topMargin; break; case Gravity.BOTTOM: - ypos = getHeight() - getPaddingBottom() - mCustomNavView.getMeasuredHeight() + ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight() - bottomMargin; break; } - x += positionChild(mCustomNavView, xpos, ypos, contentHeight); + x += positionChild(customView, xpos, ypos, contentHeight); } if (mProgressView != null) { @@ -928,9 +968,83 @@ public class ActionBarView extends AbsActionBarView { } } + @Override + public LayoutParams generateLayoutParams(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 CREATOR = + new Parcelable.Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + private static class HomeView extends FrameLayout { private View mUpView; - private View mIconView; + private ImageView mIconView; public HomeView(Context context) { this(context, null); @@ -940,12 +1054,24 @@ public class ActionBarView extends AbsActionBarView { super(context, attrs); } + public void setUp(boolean isUp) { + mUpView.setVisibility(isUp ? VISIBLE : GONE); + } + + public void setIcon(Drawable icon) { + mIconView.setImageDrawable(icon); + } + @Override protected void onFinishInflate() { mUpView = findViewById(com.android.internal.R.id.up); mIconView = (ImageView) findViewById(com.android.internal.R.id.home); } + public int getVerticalIconPadding() { + return mIconView.getPaddingTop() + mIconView.getPaddingBottom(); + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0); @@ -983,4 +1109,111 @@ public class ActionBarView extends AbsActionBarView { 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. + mExpandedActionView = null; + if (mCurrentExpandedItem != null) { + mCurrentExpandedItem.collapseActionView(); + } + 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; + 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(item.getIcon()); + mCurrentExpandedItem = item; + if (mExpandedActionView.getParent() != ActionBarView.this) { + addView(mExpandedActionView); + } + if (mExpandedHomeLayout.getParent() != ActionBarView.this) { + addView(mExpandedHomeLayout); + } + mHomeLayout.setVisibility(GONE); + 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); + return true; + } + + @Override + public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { + removeView(mExpandedActionView); + removeView(mExpandedHomeLayout); + if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) { + mHomeLayout.setVisibility(VISIBLE); + } + if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { + 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); + } + mExpandedActionView = null; + mExpandedHomeLayout.setIcon(null); + mCurrentExpandedItem = null; + requestLayout(); + item.setActionViewExpanded(false); + return true; + } + } } diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index db7621158a598..b3520da973eac 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4482,6 +4482,10 @@ + +