ActionMenuPresenter.java revision ac00a989afc2f1c559fc33174f481a0a0ef5b3d8
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; 22ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banesimport android.graphics.Rect; 23ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banesimport android.graphics.drawable.Drawable; 24bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.os.Parcel; 25bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.os.Parcelable; 26ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banesimport android.support.v4.graphics.drawable.DrawableCompat; 2749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ActionProvider; 2849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.GravityCompat; 29da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R; 3049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.transition.ActionBarTransition; 31da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.internal.view.ActionBarPolicy; 3249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.ActionMenuItemView; 3349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.BaseMenuPresenter; 3449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuBuilder; 3549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuItemImpl; 3649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuPopupHelper; 3749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuView; 3849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.SubMenuBuilder; 39bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.util.SparseBooleanArray; 4030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem; 41bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.SoundEffectConstants; 42bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View; 43bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View.MeasureSpec; 44bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.ViewGroup; 45bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.widget.ImageButton; 46bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 47bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport java.util.ArrayList; 48bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 49bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/** 50bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * MenuPresenter for building action menus as seen in the action bar and action modes. 5189208232f3b5d1451408d787872504a190bc7ee0Chris Banes * 5289208232f3b5d1451408d787872504a190bc7ee0Chris Banes * @hide 53bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */ 54bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellpublic class ActionMenuPresenter extends BaseMenuPresenter 5520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns implements ActionProvider.SubUiVisibilityListener { 56bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 5720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private static final String TAG = "ActionMenuPresenter"; 58bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 5920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private View mOverflowButton; 6020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mReserveOverflow; 6120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mReserveOverflowSet; 6220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mWidthLimit; 6320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mActionItemWidthLimit; 6420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mMaxItems; 6520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mMaxItemsSet; 6620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mStrictWidthLimit; 6720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mWidthLimitSet; 6820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mExpandedActionViewsExclusive; 69bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mMinCellSize; 71bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Group IDs that have been added as actions - used temporarily, allocated here for reuse. 7320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray(); 74bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private View mScrapActionButtonView; 76bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private OverflowPopup mOverflowPopup; 7820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private ActionButtonSubmenu mActionButtonPopup; 79bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 8020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private OpenOverflowRunnable mPostedOpenRunnable; 8149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ActionMenuPopupCallback mPopupCallback; 82bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 8320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); 8420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int mOpenSubMenuId; 85bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 8620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public ActionMenuPresenter(Context context) { 87ee7c9fb199e9b9af8d40a1f9e27d85465acf8301Chris Banes super(context, R.layout.abc_action_menu_layout, R.layout.abc_action_menu_item_layout); 88bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 89bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 9020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 9120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void initForMenu(Context context, MenuBuilder menu) { 9220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.initForMenu(context, menu); 93bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 9420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final Resources res = context.getResources(); 95bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 9620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ActionBarPolicy abp = ActionBarPolicy.get(context); 9720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mReserveOverflowSet) { 9820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mReserveOverflow = abp.showsOverflowMenuButton(); 9920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 100bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 10120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mWidthLimitSet) { 10220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mWidthLimit = abp.getEmbeddedMenuWidthLimit(); 10320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 104bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 10520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Measure for initial configuration 10620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mMaxItemsSet) { 10720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItems = abp.getMaxActionButtons(); 10820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 109bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 11020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int width = mWidthLimit; 11120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mReserveOverflow) { 11220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mOverflowButton == null) { 11320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton = new OverflowMenuButton(mSystemContext); 11420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 11520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton.measure(spec, spec); 11620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 11720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns width -= mOverflowButton.getMeasuredWidth(); 11820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 11920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton = null; 12020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 121bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 12220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionItemWidthLimit = width; 123bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 12420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density); 125bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 12620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Drop a scrap view as it may no longer reflect the proper context/config. 12720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mScrapActionButtonView = null; 128bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 12920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 13020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onConfigurationChanged(Configuration newConfig) { 13120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mMaxItemsSet) { 13220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItems = mContext.getResources().getInteger( 13307a07ce59efb770e9fb9ca53a0133e5e64a63bbcChris Banes R.integer.abc_max_action_buttons); 134bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 13520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mMenu != null) { 136d900fe072335d488f883585e3f686ef955d1ccc9Chris Banes mMenu.onItemsChanged(true); 137bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 13820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 139bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 14020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setWidthLimit(int width, boolean strict) { 14120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mWidthLimit = width; 14220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mStrictWidthLimit = strict; 14320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mWidthLimitSet = true; 144bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 145bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 14620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setReserveOverflow(boolean reserveOverflow) { 14720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mReserveOverflow = reserveOverflow; 14820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mReserveOverflowSet = true; 14920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 150bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 15120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setItemLimit(int itemCount) { 15220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItems = itemCount; 15320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItemsSet = true; 15420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 155bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 15620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setExpandedActionViewsExclusive(boolean isExclusive) { 15720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mExpandedActionViewsExclusive = isExclusive; 158bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 159bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 16020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 16120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public MenuView getMenuView(ViewGroup root) { 16220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuView result = super.getMenuView(root); 16320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((ActionMenuView) result).setPresenter(this); 16420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return result; 165bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 166bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 16720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 16849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public View getItemView(final MenuItemImpl item, View convertView, ViewGroup parent) { 16920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns View actionView = item.getActionView(); 17020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (actionView == null || item.hasCollapsibleActionView()) { 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 } 644ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes 645ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes @Override 646ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 647ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes super.onLayout(changed, left, top, right, bottom); 648ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes 649ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes // Set up the hotspot bounds to be centered on the image. 650ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes final Drawable d = getDrawable(); 651ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes final Drawable bg = getBackground(); 652ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes if (d != null && bg != null) { 653ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes final Rect bounds = d.getBounds(); 654ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes final int height = bottom - top; 655ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes final int offset = (height - bounds.width()) / 2; 656ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes final int hotspotLeft = bounds.left - offset; 657ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes final int hotspotRight = bounds.right + offset; 658ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes DrawableCompat.setHotspotBounds(bg, hotspotLeft, 0, hotspotRight, height); 659ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes } 660ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes } 661bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 662bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 66320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private class OverflowPopup extends MenuPopupHelper { 664bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 66520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public OverflowPopup(Context context, MenuBuilder menu, View anchorView, 66620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean overflowOnly) { 66749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(context, menu, anchorView, overflowOnly, R.attr.actionOverflowMenuStyle); 66849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setGravity(GravityCompat.END); 66920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setCallback(mPopupPresenterCallback); 67020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 671bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 67220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 67320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onDismiss() { 67420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onDismiss(); 67520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.close(); 67620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowPopup = null; 67720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 678bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 679bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 68049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class ActionButtonSubmenu extends MenuPopupHelper { 68149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private SubMenuBuilder mSubMenu; 68249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 68349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { 68449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(context, subMenu, null, false, 68549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes R.attr.actionOverflowMenuStyle); 68649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mSubMenu = subMenu; 68749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 68849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MenuItemImpl item = (MenuItemImpl) subMenu.getItem(); 68949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!item.isActionButton()) { 69049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Give a reasonable anchor to nested submenus. 69149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton); 69249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 69320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 69420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setCallback(mPopupPresenterCallback); 69549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 69649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean preserveIconSpacing = false; 69749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = subMenu.size(); 69849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 69949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MenuItem childItem = subMenu.getItem(i); 70049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childItem.isVisible() && childItem.getIcon() != null) { 70149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes preserveIconSpacing = true; 70249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 70349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 70449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 70549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setForceShowIcon(preserveIconSpacing); 70620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 70720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 70820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 70949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onDismiss() { 71049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onDismiss(); 71120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionButtonPopup = null; 71220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOpenSubMenuId = 0; 71320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 714bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 715bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 71649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class PopupPresenterCallback implements Callback { 71720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 71820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 71920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean onOpenSubMenu(MenuBuilder subMenu) { 72049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (subMenu == null) return false; 72120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 72220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); 72349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final Callback cb = getCallback(); 72449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return cb != null ? cb.onOpenSubMenu(subMenu) : false; 72520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 726bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 72720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 72820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 72920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (menu instanceof SubMenuBuilder) { 73020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((SubMenuBuilder) menu).getRootMenu().close(false); 73120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 73249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final Callback cb = getCallback(); 73349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (cb != null) { 73449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes cb.onCloseMenu(menu, allMenusAreClosing); 73549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 73620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 737bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 738bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 73920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private class OpenOverflowRunnable implements Runnable { 74020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private OverflowPopup mPopup; 74120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 74220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public OpenOverflowRunnable(OverflowPopup popup) { 74320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPopup = popup; 74420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 74520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 74620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void run() { 74720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.changeMenuMode(); 74820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final View menuView = (View) mMenuView; 74920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) { 75020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowPopup = mPopup; 75120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 75220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPostedOpenRunnable = null; 75320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 754bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 75549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 75649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class ActionMenuPopupCallback extends ActionMenuItemView.PopupCallback { 75749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 75849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public ListPopupWindow getPopup() { 75949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null; 76049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 76149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 762bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell} 763