ActionMenuPresenter.java revision 49c78900da0d43140fb602431fb93212bd7f6c70
1bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/* 249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Copyright (C) 2014 The Android Open Source Project 3bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * 4bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * you may not use this file except in compliance with the License. 6bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * You may obtain a copy of the License at 7bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * 8bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * http://www.apache.org/licenses/LICENSE-2.0 9bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * 10bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Unless required by applicable law or agreed to in writing, software 11bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * See the License for the specific language governing permissions and 14bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * limitations under the License. 15bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */ 16bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 1749c78900da0d43140fb602431fb93212bd7f6c70Chris Banespackage android.support.v7.widget; 18bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 19bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Context; 20bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.Configuration; 21bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.Resources; 22bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.os.Parcel; 23bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.os.Parcelable; 2449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ActionProvider; 2549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.GravityCompat; 26da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R; 2749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.transition.ActionBarTransition; 28da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.internal.view.ActionBarPolicy; 2949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.ActionMenuItemView; 3049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.BaseMenuPresenter; 3149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuBuilder; 3249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuItemImpl; 3349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuPopupHelper; 3449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuView; 3549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.SubMenuBuilder; 36bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.util.SparseBooleanArray; 3730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem; 38bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.SoundEffectConstants; 39bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View; 40bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View.MeasureSpec; 41bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.ViewGroup; 42bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.widget.ImageButton; 43bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 44bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport java.util.ArrayList; 45bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 46bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/** 47bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * MenuPresenter for building action menus as seen in the action bar and action modes. 4889208232f3b5d1451408d787872504a190bc7ee0Chris Banes * 4989208232f3b5d1451408d787872504a190bc7ee0Chris Banes * @hide 50bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */ 51bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellpublic class ActionMenuPresenter extends BaseMenuPresenter 5220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns implements ActionProvider.SubUiVisibilityListener { 53bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 5420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private static final String TAG = "ActionMenuPresenter"; 55bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 5620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private View mOverflowButton; 5720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mReserveOverflow; 5820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mReserveOverflowSet; 5920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mWidthLimit; 6020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mActionItemWidthLimit; 6120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mMaxItems; 6220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mMaxItemsSet; 6320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mStrictWidthLimit; 6420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mWidthLimitSet; 6520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mExpandedActionViewsExclusive; 66bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 6720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mMinCellSize; 68bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 6920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Group IDs that have been added as actions - used temporarily, allocated here for reuse. 7020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray(); 71bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private View mScrapActionButtonView; 73bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private OverflowPopup mOverflowPopup; 7520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private ActionButtonSubmenu mActionButtonPopup; 76bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private OpenOverflowRunnable mPostedOpenRunnable; 7849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ActionMenuPopupCallback mPopupCallback; 79bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 8020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); 8120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int mOpenSubMenuId; 82bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 8320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public ActionMenuPresenter(Context context) { 84ee7c9fb199e9b9af8d40a1f9e27d85465acf8301Chris Banes super(context, R.layout.abc_action_menu_layout, R.layout.abc_action_menu_item_layout); 85bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 86bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 8720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 8820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void initForMenu(Context context, MenuBuilder menu) { 8920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.initForMenu(context, menu); 90bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 9120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final Resources res = context.getResources(); 92bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 9320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ActionBarPolicy abp = ActionBarPolicy.get(context); 9420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mReserveOverflowSet) { 9520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mReserveOverflow = abp.showsOverflowMenuButton(); 9620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 97bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 9820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mWidthLimitSet) { 9920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mWidthLimit = abp.getEmbeddedMenuWidthLimit(); 10020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 101bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 10220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Measure for initial configuration 10320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mMaxItemsSet) { 10420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItems = abp.getMaxActionButtons(); 10520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 106bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 10720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int width = mWidthLimit; 10820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mReserveOverflow) { 10920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mOverflowButton == null) { 11020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton = new OverflowMenuButton(mSystemContext); 11120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 11220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton.measure(spec, spec); 11320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 11420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns width -= mOverflowButton.getMeasuredWidth(); 11520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 11620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton = null; 11720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 118bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 11920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionItemWidthLimit = width; 120bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 12120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density); 122bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 12320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Drop a scrap view as it may no longer reflect the proper context/config. 12420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mScrapActionButtonView = null; 125bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 12620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 12720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onConfigurationChanged(Configuration newConfig) { 12820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mMaxItemsSet) { 12920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItems = mContext.getResources().getInteger( 13007a07ce59efb770e9fb9ca53a0133e5e64a63bbcChris Banes R.integer.abc_max_action_buttons); 131bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 13220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mMenu != null) { 133d900fe072335d488f883585e3f686ef955d1ccc9Chris Banes mMenu.onItemsChanged(true); 134bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 13520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 136bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 13720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setWidthLimit(int width, boolean strict) { 13820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mWidthLimit = width; 13920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mStrictWidthLimit = strict; 14020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mWidthLimitSet = true; 141bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 142bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 14320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setReserveOverflow(boolean reserveOverflow) { 14420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mReserveOverflow = reserveOverflow; 14520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mReserveOverflowSet = true; 14620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 147bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 14820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setItemLimit(int itemCount) { 14920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItems = itemCount; 15020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItemsSet = true; 15120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 152bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 15320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setExpandedActionViewsExclusive(boolean isExclusive) { 15420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mExpandedActionViewsExclusive = isExclusive; 155bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 156bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 15720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 15820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public MenuView getMenuView(ViewGroup root) { 15920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuView result = super.getMenuView(root); 16020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((ActionMenuView) result).setPresenter(this); 16120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return result; 162bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 163bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 16420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 16549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public View getItemView(final MenuItemImpl item, View convertView, ViewGroup parent) { 16620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns View actionView = item.getActionView(); 16720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (actionView == null || item.hasCollapsibleActionView()) { 16820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!(convertView instanceof ActionMenuItemView)) { 16920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns convertView = null; 17020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 17120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns actionView = super.getItemView(item, convertView, parent); 17220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 17320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE); 174bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 17520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ActionMenuView menuParent = (ActionMenuView) parent; 17620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ViewGroup.LayoutParams lp = actionView.getLayoutParams(); 17720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!menuParent.checkLayoutParams(lp)) { 17820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns actionView.setLayoutParams(menuParent.generateLayoutParams(lp)); 17920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 18020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return actionView; 181bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 182bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 18320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 18420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) { 18520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns itemView.initialize(item, 0); 18620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 18720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ActionMenuView menuView = (ActionMenuView) mMenuView; 18849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final ActionMenuItemView actionItemView = (ActionMenuItemView) itemView; 18981173a86853974bb27d4197a0f0768922f8205caTrevor Johns actionItemView.setItemInvoker(menuView); 19049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 19149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mPopupCallback == null) { 19249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mPopupCallback = new ActionMenuPopupCallback(); 19349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 19449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes actionItemView.setPopupCallback(mPopupCallback); 195bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 196bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 197bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell @Override 19820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { 19920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return item.isActionButton(); 200bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 201bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 202bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell @Override 20320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void updateMenuView(boolean cleared) { 20449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final ViewGroup menuViewParent = (ViewGroup) ((View) mMenuView).getParent(); 20549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (menuViewParent != null) { 20649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBarTransition.beginDelayedTransition(menuViewParent); 20749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 20820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.updateMenuView(cleared); 20920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 21049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ((View) mMenuView).requestLayout(); 211176a17e30644b1d5a4206cc462268d151e43949bChris Banes 21220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mMenu != null) { 21320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems(); 21420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int count = actionItems.size(); 21520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int i = 0; i < count; i++) { 21630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell final ActionProvider provider = actionItems.get(i).getSupportActionProvider(); 21720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (provider != null) { 21820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns provider.setSubUiVisibilityListener(this); 21920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 22020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 22120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 222bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 22320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ArrayList<MenuItemImpl> nonActionItems = mMenu != null ? 22420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.getNonActionItems() : null; 225bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 22620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean hasOverflow = false; 22720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mReserveOverflow && nonActionItems != null) { 22820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int count = nonActionItems.size(); 22920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (count == 1) { 23020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns hasOverflow = !nonActionItems.get(0).isActionViewExpanded(); 23120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 23220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns hasOverflow = count > 0; 23320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 23420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 235bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 23620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (hasOverflow) { 23720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mOverflowButton == null) { 23820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton = new OverflowMenuButton(mSystemContext); 23920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 24020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ViewGroup parent = (ViewGroup) mOverflowButton.getParent(); 24120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (parent != mMenuView) { 24220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (parent != null) { 24320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns parent.removeView(mOverflowButton); 24420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 24520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ActionMenuView menuView = (ActionMenuView) mMenuView; 24620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams()); 24720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 24820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) { 24920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((ViewGroup) mMenuView).removeView(mOverflowButton); 25020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 251bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 25220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow); 253bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 254bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 255bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell @Override 25620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean filterLeftoverView(ViewGroup parent, int childIndex) { 25749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (parent.getChildAt(childIndex) == mOverflowButton) return false; 25820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return super.filterLeftoverView(parent, childIndex); 25920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 26020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 26120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 26249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!subMenu.hasVisibleItems()) return false; 26320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 26420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SubMenuBuilder topSubMenu = subMenu; 26520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns while (topSubMenu.getParentMenu() != mMenu) { 26620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu(); 26720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 26820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns View anchor = findViewForItem(topSubMenu.getItem()); 26920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (anchor == null) { 27049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOverflowButton == null) return false; 27120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns anchor = mOverflowButton; 27220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 27320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 27420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOpenSubMenuId = subMenu.getItem().getItemId(); 27549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu); 27649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionButtonPopup.setAnchorView(anchor); 27749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionButtonPopup.show(); 27820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onSubMenuSelected(subMenu); 279bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell return true; 28020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 28120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 28220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private View findViewForItem(MenuItem item) { 28320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ViewGroup parent = (ViewGroup) mMenuView; 28449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (parent == null) return null; 28520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 28620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int count = parent.getChildCount(); 28720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int i = 0; i < count; i++) { 28820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final View child = parent.getChildAt(i); 28920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (child instanceof MenuView.ItemView && 29020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((MenuView.ItemView) child).getItemData() == item) { 29120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return child; 29220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 29320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 29420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return null; 29520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 29620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 29720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 29820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Display the overflow menu if one is present. 29920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if the overflow menu was shown, false otherwise. 30020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 30120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean showOverflowMenu() { 30220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null && 30349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) { 30420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true); 30520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPostedOpenRunnable = new OpenOverflowRunnable(popup); 30620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Post this for later; we might still need a layout for the anchor to be right. 30720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((View) mMenuView).post(mPostedOpenRunnable); 30820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 30920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // ActionMenuPresenter uses null as a callback argument here 31020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // to indicate overflow is opening. 31120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onSubMenuSelected(null); 31220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 31320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 31420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 31520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 31620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 31720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 31820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 31920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Hide the overflow menu if it is currently showing. 32020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 32120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if the overflow menu was hidden, false otherwise. 32220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 32320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean hideOverflowMenu() { 32420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mPostedOpenRunnable != null && mMenuView != null) { 32520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((View) mMenuView).removeCallbacks(mPostedOpenRunnable); 32620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPostedOpenRunnable = null; 32720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 32820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 32920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 33020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuPopupHelper popup = mOverflowPopup; 33120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (popup != null) { 33220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns popup.dismiss(); 33320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 33420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 33520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 33620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 33720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 33820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 33920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Dismiss all popup menus - overflow and submenus. 34020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if popups were dismissed, false otherwise. (This can be because none were open.) 34120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 34220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean dismissPopupMenus() { 34320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean result = hideOverflowMenu(); 34420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns result |= hideSubMenus(); 34520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return result; 34620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 34720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 34820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 34920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Dismiss all submenu popups. 35020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 35120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if popups were dismissed, false otherwise. (This can be because none were open.) 35220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 35320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean hideSubMenus() { 35420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mActionButtonPopup != null) { 35520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionButtonPopup.dismiss(); 35620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 35720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 35820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 35920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 36020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 36120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 36220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if the overflow menu is currently showing 36320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 36420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean isOverflowMenuShowing() { 36520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return mOverflowPopup != null && mOverflowPopup.isShowing(); 36620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 36720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 36849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isOverflowMenuShowPending() { 36949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mPostedOpenRunnable != null || isOverflowMenuShowing(); 37049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 37149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 37220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 37320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if space has been reserved in the action menu for an overflow item. 37420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 37520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean isOverflowReserved() { 37620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return mReserveOverflow; 37720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 37820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 37920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean flagActionItems() { 38020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems(); 38120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int itemsSize = visibleItems.size(); 38220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int maxActions = mMaxItems; 38320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int widthLimit = mActionItemWidthLimit; 38420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 38520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ViewGroup parent = (ViewGroup) mMenuView; 38620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 38720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int requiredItems = 0; 38820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int requestedItems = 0; 38920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int firstActionWidth = 0; 39020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean hasOverflow = false; 39120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int i = 0; i < itemsSize; i++) { 39220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuItemImpl item = visibleItems.get(i); 39320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (item.requiresActionButton()) { 39420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns requiredItems++; 39520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else if (item.requestsActionButton()) { 39620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns requestedItems++; 39720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 39820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns hasOverflow = true; 39920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 40020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) { 40120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Overflow everything if we have an expanded action view and we're 40220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // space constrained. 40320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns maxActions = 0; 40420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 40520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 40620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 40720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Reserve a spot for the overflow item if needed. 40820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mReserveOverflow && 40920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns (hasOverflow || requiredItems + requestedItems > maxActions)) { 41020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns maxActions--; 41120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 41220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns maxActions -= requiredItems; 413bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 41420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final SparseBooleanArray seenGroups = mActionButtonGroups; 41520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns seenGroups.clear(); 41620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 41720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int cellSize = 0; 41820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int cellsRemaining = 0; 41920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mStrictWidthLimit) { 42020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellsRemaining = widthLimit / mMinCellSize; 42120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int cellSizeRemaining = widthLimit % mMinCellSize; 42220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining; 42320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 42420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 42520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Flag as many more requested items as will fit. 42620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int i = 0; i < itemsSize; i++) { 42720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuItemImpl item = visibleItems.get(i); 42820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 42920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (item.requiresActionButton()) { 43020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns View v = getItemView(item, mScrapActionButtonView, parent); 43120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mScrapActionButtonView == null) { 43220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mScrapActionButtonView = v; 43320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 43420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mStrictWidthLimit) { 43520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellsRemaining -= ActionMenuView.measureChildForCells(v, 43620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellSize, cellsRemaining, querySpec, 0); 43720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 43820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns v.measure(querySpec, querySpec); 43920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 44020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int measuredWidth = v.getMeasuredWidth(); 44120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns widthLimit -= measuredWidth; 44220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (firstActionWidth == 0) { 44320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns firstActionWidth = measuredWidth; 44420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 44520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int groupId = item.getGroupId(); 44620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (groupId != 0) { 44720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns seenGroups.put(groupId, true); 44820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 44920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns item.setIsActionButton(true); 45020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else if (item.requestsActionButton()) { 45120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Items in a group with other items that already have an action slot 45220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // can break the max actions rule, but not the width limit. 45320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int groupId = item.getGroupId(); 45420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final boolean inGroup = seenGroups.get(groupId); 45520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 && 45620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns (!mStrictWidthLimit || cellsRemaining > 0); 45720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 45820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (isAction) { 45920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns View v = getItemView(item, mScrapActionButtonView, parent); 46020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mScrapActionButtonView == null) { 46120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mScrapActionButtonView = v; 46220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 46320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mStrictWidthLimit) { 46420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int cells = ActionMenuView.measureChildForCells(v, 46520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellSize, cellsRemaining, querySpec, 0); 46620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellsRemaining -= cells; 46720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (cells == 0) { 46820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns isAction = false; 46920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 47020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 47120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns v.measure(querySpec, querySpec); 47220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 47320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int measuredWidth = v.getMeasuredWidth(); 47420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns widthLimit -= measuredWidth; 47520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (firstActionWidth == 0) { 47620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns firstActionWidth = measuredWidth; 47720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 47820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 47920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mStrictWidthLimit) { 48020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns isAction &= widthLimit >= 0; 48120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 48220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Did this push the entire first item past the limit? 48320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns isAction &= widthLimit + firstActionWidth > 0; 48420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 48520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 48620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 48720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (isAction && groupId != 0) { 48820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns seenGroups.put(groupId, true); 48920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else if (inGroup) { 49020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // We broke the width limit. Demote the whole group, they all overflow now. 49120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns seenGroups.put(groupId, false); 49220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int j = 0; j < i; j++) { 49320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuItemImpl areYouMyGroupie = visibleItems.get(j); 49420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (areYouMyGroupie.getGroupId() == groupId) { 49520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Give back the action slot 49649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (areYouMyGroupie.isActionButton()) maxActions++; 49720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns areYouMyGroupie.setIsActionButton(false); 49820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 49920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 50020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 50120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 50249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isAction) maxActions--; 50320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 50420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns item.setIsActionButton(isAction); 50549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 50649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Neither requires nor requests an action button. 50749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes item.setIsActionButton(false); 50820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 50920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 51020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 511bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 512bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 51320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 51420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 51520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns dismissPopupMenus(); 51620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onCloseMenu(menu, allMenusAreClosing); 517bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 518bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 51920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 52020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public Parcelable onSaveInstanceState() { 52120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SavedState state = new SavedState(); 52220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns state.openSubMenuId = mOpenSubMenuId; 52320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return state; 524bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 525bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 52620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 52720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onRestoreInstanceState(Parcelable state) { 52820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SavedState saved = (SavedState) state; 52920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (saved.openSubMenuId > 0) { 53020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuItem item = mMenu.findItem(saved.openSubMenuId); 53120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (item != null) { 53220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); 53320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns onSubMenuSelected(subMenu); 53420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 53520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 536bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 537bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 538bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell @Override 53920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onSubUiVisibilityChanged(boolean isVisible) { 54020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (isVisible) { 54120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Not a submenu, but treat it like one. 54220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onSubMenuSelected(null); 54320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 54420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.close(false); 54520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 546bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 547bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 54849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setMenuView(ActionMenuView menuView) { 54949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mMenuView = menuView; 55049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes menuView.initialize(mMenu); 55149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 552bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 55349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private static class SavedState implements Parcelable { 55420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public int openSubMenuId; 555bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 55620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SavedState() { 55720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 558bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 55920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SavedState(Parcel in) { 56020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns openSubMenuId = in.readInt(); 56120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 56220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 56320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 56420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public int describeContents() { 56520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return 0; 56620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 567bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 56820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 56920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void writeToParcel(Parcel dest, int flags) { 57020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns dest.writeInt(openSubMenuId); 571bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 57220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 57320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public static final Parcelable.Creator<SavedState> CREATOR 57420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns = new Parcelable.Creator<SavedState>() { 57520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public SavedState createFromParcel(Parcel in) { 57620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return new SavedState(in); 57720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 57820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 57920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public SavedState[] newArray(int size) { 58020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return new SavedState[size]; 58120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 58220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns }; 583bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 584bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 58549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class OverflowMenuButton extends ImageButton implements ActionMenuView.ActionMenuChildView { 58620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public OverflowMenuButton(Context context) { 58720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super(context, null, R.attr.actionOverflowButtonStyle); 58820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 58920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setClickable(true); 59020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setFocusable(true); 59120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setVisibility(VISIBLE); 59220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setEnabled(true); 59349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setOnTouchListener(new ListPopupWindow.ForwardingListener(this) { 59449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 59549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public ListPopupWindow getPopup() { 59649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOverflowPopup == null) { 59749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return null; 59849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 59949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mOverflowPopup.getPopup(); 60149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 60249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 60449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean onForwardingStarted() { 60549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes showOverflowMenu(); 60649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return true; 60749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 60849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 61049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean onForwardingStopped() { 61149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Displaying the popup occurs asynchronously, so wait for 61249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // the runnable to finish before deciding whether to stop 61349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // forwarding. 61449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mPostedOpenRunnable != null) { 61549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 61649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 61749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes hideOverflowMenu(); 61949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return true; 62049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 62149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }); 62220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 62320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 62420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 62520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean performClick() { 62620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (super.performClick()) { 62720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 62820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 62920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 63020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns playSoundEffect(SoundEffectConstants.CLICK); 63120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns showOverflowMenu(); 63220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 63320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 63420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 63549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 63620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean needsDividerBefore() { 63720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 63820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 63920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 64049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 64120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean needsDividerAfter() { 64220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 64320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 644bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 645bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 64620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private class OverflowPopup extends MenuPopupHelper { 647bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 64820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public OverflowPopup(Context context, MenuBuilder menu, View anchorView, 64920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean overflowOnly) { 65049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(context, menu, anchorView, overflowOnly, R.attr.actionOverflowMenuStyle); 65149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setGravity(GravityCompat.END); 65220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setCallback(mPopupPresenterCallback); 65320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 654bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 65520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 65620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onDismiss() { 65720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onDismiss(); 65820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.close(); 65920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowPopup = null; 66020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 661bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 662bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 66349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class ActionButtonSubmenu extends MenuPopupHelper { 66449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private SubMenuBuilder mSubMenu; 66549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 66649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { 66749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(context, subMenu, null, false, 66849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes R.attr.actionOverflowMenuStyle); 66949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mSubMenu = subMenu; 67049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 67149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MenuItemImpl item = (MenuItemImpl) subMenu.getItem(); 67249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!item.isActionButton()) { 67349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Give a reasonable anchor to nested submenus. 67449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton); 67549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 67620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 67720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setCallback(mPopupPresenterCallback); 67849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 67949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean preserveIconSpacing = false; 68049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = subMenu.size(); 68149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 68249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MenuItem childItem = subMenu.getItem(i); 68349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childItem.isVisible() && childItem.getIcon() != null) { 68449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes preserveIconSpacing = true; 68549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 68649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 68749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 68849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setForceShowIcon(preserveIconSpacing); 68920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 69020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 69120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 69249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onDismiss() { 69349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onDismiss(); 69420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionButtonPopup = null; 69520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOpenSubMenuId = 0; 69620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 697bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 698bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 69949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class PopupPresenterCallback implements Callback { 70020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 70120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 70220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean onOpenSubMenu(MenuBuilder subMenu) { 70349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (subMenu == null) return false; 70420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 70520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); 70649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final Callback cb = getCallback(); 70749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return cb != null ? cb.onOpenSubMenu(subMenu) : false; 70820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 709bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 71020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 71120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 71220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (menu instanceof SubMenuBuilder) { 71320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((SubMenuBuilder) menu).getRootMenu().close(false); 71420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 71549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final Callback cb = getCallback(); 71649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (cb != null) { 71749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes cb.onCloseMenu(menu, allMenusAreClosing); 71849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 71920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 720bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 721bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 72220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private class OpenOverflowRunnable implements Runnable { 72320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private OverflowPopup mPopup; 72420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 72520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public OpenOverflowRunnable(OverflowPopup popup) { 72620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPopup = popup; 72720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 72820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 72920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void run() { 73020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.changeMenuMode(); 73120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final View menuView = (View) mMenuView; 73220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) { 73320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowPopup = mPopup; 73420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 73520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPostedOpenRunnable = null; 73620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 737bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 73849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 73949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class ActionMenuPopupCallback extends ActionMenuItemView.PopupCallback { 74049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 74149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public ListPopupWindow getPopup() { 74249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null; 74349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 74449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 745bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell} 746