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.drawable.Drawable; 23bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.os.Parcel; 24bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.os.Parcelable; 25ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banesimport android.support.v4.graphics.drawable.DrawableCompat; 2649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ActionProvider; 2749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.GravityCompat; 28da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R; 2949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.transition.ActionBarTransition; 30da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.internal.view.ActionBarPolicy; 3149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.ActionMenuItemView; 3249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.BaseMenuPresenter; 3349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuBuilder; 3449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuItemImpl; 3549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuPopupHelper; 3649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuView; 3749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.SubMenuBuilder; 38469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.support.v7.internal.widget.TintImageView; 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 Powell 46bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport java.util.ArrayList; 47bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 48bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/** 49bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * MenuPresenter for building action menus as seen in the action bar and action modes. 5089208232f3b5d1451408d787872504a190bc7ee0Chris Banes * 5189208232f3b5d1451408d787872504a190bc7ee0Chris Banes * @hide 52bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */ 53bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellpublic class ActionMenuPresenter extends BaseMenuPresenter 5420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns implements ActionProvider.SubUiVisibilityListener { 55bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 5620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private static final String TAG = "ActionMenuPresenter"; 57bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 5820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private View mOverflowButton; 5920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mReserveOverflow; 6020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mReserveOverflowSet; 6120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mWidthLimit; 6220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mActionItemWidthLimit; 6320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mMaxItems; 6420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mMaxItemsSet; 6520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mStrictWidthLimit; 6620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mWidthLimitSet; 6720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private boolean mExpandedActionViewsExclusive; 68bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 6920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private int mMinCellSize; 70bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Group IDs that have been added as actions - used temporarily, allocated here for reuse. 7220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray(); 73bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private View mScrapActionButtonView; 75bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private OverflowPopup mOverflowPopup; 7720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private ActionButtonSubmenu mActionButtonPopup; 78bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 7920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private OpenOverflowRunnable mPostedOpenRunnable; 8049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private ActionMenuPopupCallback mPopupCallback; 81bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 8220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); 8320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int mOpenSubMenuId; 84bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 8520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public ActionMenuPresenter(Context context) { 86ee7c9fb199e9b9af8d40a1f9e27d85465acf8301Chris Banes super(context, R.layout.abc_action_menu_layout, R.layout.abc_action_menu_item_layout); 87bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 88bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 8920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 9020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void initForMenu(Context context, MenuBuilder menu) { 9120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.initForMenu(context, menu); 92bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 9320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final Resources res = context.getResources(); 94bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 9520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ActionBarPolicy abp = ActionBarPolicy.get(context); 9620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mReserveOverflowSet) { 9720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mReserveOverflow = abp.showsOverflowMenuButton(); 9820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 99bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 10020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mWidthLimitSet) { 10120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mWidthLimit = abp.getEmbeddedMenuWidthLimit(); 10220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 103bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 10420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Measure for initial configuration 10520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mMaxItemsSet) { 10620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItems = abp.getMaxActionButtons(); 10720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 108bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 10920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int width = mWidthLimit; 11020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mReserveOverflow) { 11120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mOverflowButton == null) { 11220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton = new OverflowMenuButton(mSystemContext); 11320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 11420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton.measure(spec, spec); 11520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 11620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns width -= mOverflowButton.getMeasuredWidth(); 11720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 11820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton = null; 11920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 120bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 12120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionItemWidthLimit = width; 122bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 12320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density); 124bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 12520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Drop a scrap view as it may no longer reflect the proper context/config. 12620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mScrapActionButtonView = null; 127bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 12820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 12920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onConfigurationChanged(Configuration newConfig) { 13020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mMaxItemsSet) { 13120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItems = mContext.getResources().getInteger( 13207a07ce59efb770e9fb9ca53a0133e5e64a63bbcChris Banes R.integer.abc_max_action_buttons); 133bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 13420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mMenu != null) { 135d900fe072335d488f883585e3f686ef955d1ccc9Chris Banes mMenu.onItemsChanged(true); 136bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 13720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 138bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 13920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setWidthLimit(int width, boolean strict) { 14020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mWidthLimit = width; 14120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mStrictWidthLimit = strict; 14220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mWidthLimitSet = true; 143bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 144bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 14520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setReserveOverflow(boolean reserveOverflow) { 14620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mReserveOverflow = reserveOverflow; 14720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mReserveOverflowSet = true; 14820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 149bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 15020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setItemLimit(int itemCount) { 15120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItems = itemCount; 15220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMaxItemsSet = true; 15320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 154bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 15520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void setExpandedActionViewsExclusive(boolean isExclusive) { 15620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mExpandedActionViewsExclusive = isExclusive; 157bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 158bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 15920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 16020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public MenuView getMenuView(ViewGroup root) { 16120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuView result = super.getMenuView(root); 16220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((ActionMenuView) result).setPresenter(this); 16320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return result; 164bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 165bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 16620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 16749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public View getItemView(final MenuItemImpl item, View convertView, ViewGroup parent) { 16820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns View actionView = item.getActionView(); 16920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (actionView == null || item.hasCollapsibleActionView()) { 17020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns actionView = super.getItemView(item, convertView, parent); 17120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 17220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE); 173bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 17420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ActionMenuView menuParent = (ActionMenuView) parent; 17520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ViewGroup.LayoutParams lp = actionView.getLayoutParams(); 17620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!menuParent.checkLayoutParams(lp)) { 17720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns actionView.setLayoutParams(menuParent.generateLayoutParams(lp)); 17820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 17920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return actionView; 180bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 181bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 18220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 18320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) { 18420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns itemView.initialize(item, 0); 18520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 18620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ActionMenuView menuView = (ActionMenuView) mMenuView; 18749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final ActionMenuItemView actionItemView = (ActionMenuItemView) itemView; 18881173a86853974bb27d4197a0f0768922f8205caTrevor Johns actionItemView.setItemInvoker(menuView); 18949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 19049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mPopupCallback == null) { 19149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mPopupCallback = new ActionMenuPopupCallback(); 19249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 19349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes actionItemView.setPopupCallback(mPopupCallback); 194bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 195bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 196bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell @Override 19720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { 19820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return item.isActionButton(); 199bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 200bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 201bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell @Override 20220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void updateMenuView(boolean cleared) { 20349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final ViewGroup menuViewParent = (ViewGroup) ((View) mMenuView).getParent(); 20449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (menuViewParent != null) { 20549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBarTransition.beginDelayedTransition(menuViewParent); 20649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 20720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.updateMenuView(cleared); 20820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 20949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ((View) mMenuView).requestLayout(); 210176a17e30644b1d5a4206cc462268d151e43949bChris Banes 21120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mMenu != null) { 21220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems(); 21320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int count = actionItems.size(); 21420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int i = 0; i < count; i++) { 21530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell final ActionProvider provider = actionItems.get(i).getSupportActionProvider(); 21620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (provider != null) { 21720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns provider.setSubUiVisibilityListener(this); 21820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 21920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 22020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 221bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 22220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ArrayList<MenuItemImpl> nonActionItems = mMenu != null ? 22320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.getNonActionItems() : null; 224bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 22520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean hasOverflow = false; 22620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mReserveOverflow && nonActionItems != null) { 22720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int count = nonActionItems.size(); 22820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (count == 1) { 22920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns hasOverflow = !nonActionItems.get(0).isActionViewExpanded(); 23020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 23120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns hasOverflow = count > 0; 23220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 23320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 234bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 23520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (hasOverflow) { 23620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mOverflowButton == null) { 23720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowButton = new OverflowMenuButton(mSystemContext); 23820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 23920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ViewGroup parent = (ViewGroup) mOverflowButton.getParent(); 24020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (parent != mMenuView) { 24120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (parent != null) { 24220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns parent.removeView(mOverflowButton); 24320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 24420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ActionMenuView menuView = (ActionMenuView) mMenuView; 24520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams()); 24620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 24720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) { 24820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((ViewGroup) mMenuView).removeView(mOverflowButton); 24920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 250bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 25120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow); 252bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 253bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 254bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell @Override 25520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean filterLeftoverView(ViewGroup parent, int childIndex) { 25649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (parent.getChildAt(childIndex) == mOverflowButton) return false; 25720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return super.filterLeftoverView(parent, childIndex); 25820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 25920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 26020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 26149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!subMenu.hasVisibleItems()) return false; 26220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 26320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SubMenuBuilder topSubMenu = subMenu; 26420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns while (topSubMenu.getParentMenu() != mMenu) { 26520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu(); 26620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 26720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns View anchor = findViewForItem(topSubMenu.getItem()); 26820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (anchor == null) { 26949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOverflowButton == null) return false; 27020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns anchor = mOverflowButton; 27120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 27220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 27320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOpenSubMenuId = subMenu.getItem().getItemId(); 27449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu); 27549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionButtonPopup.setAnchorView(anchor); 27649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mActionButtonPopup.show(); 27720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onSubMenuSelected(subMenu); 278bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell return true; 27920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 28020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 28120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private View findViewForItem(MenuItem item) { 28220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ViewGroup parent = (ViewGroup) mMenuView; 28349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (parent == null) return null; 28420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 28520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int count = parent.getChildCount(); 28620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int i = 0; i < count; i++) { 28720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final View child = parent.getChildAt(i); 28820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (child instanceof MenuView.ItemView && 28920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((MenuView.ItemView) child).getItemData() == item) { 29020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return child; 29120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 29220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 29320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return null; 29420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 29520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 29620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 29720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Display the overflow menu if one is present. 29820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if the overflow menu was shown, false otherwise. 29920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 30020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean showOverflowMenu() { 30120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null && 30249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) { 30320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true); 30420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPostedOpenRunnable = new OpenOverflowRunnable(popup); 30520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Post this for later; we might still need a layout for the anchor to be right. 30620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((View) mMenuView).post(mPostedOpenRunnable); 30720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 30820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // ActionMenuPresenter uses null as a callback argument here 30920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // to indicate overflow is opening. 31020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onSubMenuSelected(null); 31120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 31220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 31320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 31420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 31520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 31620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 31720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 31820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Hide the overflow menu if it is currently showing. 31920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 32020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if the overflow menu was hidden, false otherwise. 32120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 32220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean hideOverflowMenu() { 32320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mPostedOpenRunnable != null && mMenuView != null) { 32420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((View) mMenuView).removeCallbacks(mPostedOpenRunnable); 32520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPostedOpenRunnable = null; 32620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 32720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 32820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 32920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuPopupHelper popup = mOverflowPopup; 33020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (popup != null) { 33120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns popup.dismiss(); 33220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 33320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 33420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 33520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 33620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 33720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 33820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Dismiss all popup menus - overflow and submenus. 33920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if popups were dismissed, false otherwise. (This can be because none were open.) 34020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 34120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean dismissPopupMenus() { 34220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean result = hideOverflowMenu(); 34320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns result |= hideSubMenus(); 34420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return result; 34520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 34620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 34720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 34820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Dismiss all submenu popups. 34920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 35020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if popups were dismissed, false otherwise. (This can be because none were open.) 35120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 35220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean hideSubMenus() { 35320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mActionButtonPopup != null) { 35420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionButtonPopup.dismiss(); 35520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 35620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 35720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 35820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 35920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 36020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 36120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if the overflow menu is currently showing 36220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 36320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean isOverflowMenuShowing() { 36420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return mOverflowPopup != null && mOverflowPopup.isShowing(); 36520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 36620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 36749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isOverflowMenuShowPending() { 36849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mPostedOpenRunnable != null || isOverflowMenuShowing(); 36949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 37049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 37120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 37220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if space has been reserved in the action menu for an overflow item. 37320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 37420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean isOverflowReserved() { 37520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return mReserveOverflow; 37620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 37720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 37820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean flagActionItems() { 37920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems(); 38020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int itemsSize = visibleItems.size(); 38120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int maxActions = mMaxItems; 38220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int widthLimit = mActionItemWidthLimit; 38320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 38420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final ViewGroup parent = (ViewGroup) mMenuView; 38520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 38620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int requiredItems = 0; 38720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int requestedItems = 0; 38820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int firstActionWidth = 0; 38920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean hasOverflow = false; 39020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int i = 0; i < itemsSize; i++) { 39120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuItemImpl item = visibleItems.get(i); 39220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (item.requiresActionButton()) { 39320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns requiredItems++; 39420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else if (item.requestsActionButton()) { 39520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns requestedItems++; 39620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 39720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns hasOverflow = true; 39820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 39920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) { 40020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Overflow everything if we have an expanded action view and we're 40120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // space constrained. 40220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns maxActions = 0; 40320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 40420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 40520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 40620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Reserve a spot for the overflow item if needed. 40720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mReserveOverflow && 40820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns (hasOverflow || requiredItems + requestedItems > maxActions)) { 40920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns maxActions--; 41020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 41120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns maxActions -= requiredItems; 412bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 41320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final SparseBooleanArray seenGroups = mActionButtonGroups; 41420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns seenGroups.clear(); 41520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 41620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int cellSize = 0; 41720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int cellsRemaining = 0; 41820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mStrictWidthLimit) { 41920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellsRemaining = widthLimit / mMinCellSize; 42020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int cellSizeRemaining = widthLimit % mMinCellSize; 42120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining; 42220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 42320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 42420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Flag as many more requested items as will fit. 42520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int i = 0; i < itemsSize; i++) { 42620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuItemImpl item = visibleItems.get(i); 42720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 42820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (item.requiresActionButton()) { 42920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns View v = getItemView(item, mScrapActionButtonView, parent); 43020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mScrapActionButtonView == null) { 43120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mScrapActionButtonView = v; 43220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 43320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mStrictWidthLimit) { 43420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellsRemaining -= ActionMenuView.measureChildForCells(v, 43520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellSize, cellsRemaining, querySpec, 0); 43620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 43720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns v.measure(querySpec, querySpec); 43820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 43920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int measuredWidth = v.getMeasuredWidth(); 44020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns widthLimit -= measuredWidth; 44120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (firstActionWidth == 0) { 44220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns firstActionWidth = measuredWidth; 44320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 44420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int groupId = item.getGroupId(); 44520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (groupId != 0) { 44620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns seenGroups.put(groupId, true); 44720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 44820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns item.setIsActionButton(true); 44920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else if (item.requestsActionButton()) { 45020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Items in a group with other items that already have an action slot 45120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // can break the max actions rule, but not the width limit. 45220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int groupId = item.getGroupId(); 45320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final boolean inGroup = seenGroups.get(groupId); 45420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 && 45520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns (!mStrictWidthLimit || cellsRemaining > 0); 45620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 45720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (isAction) { 45820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns View v = getItemView(item, mScrapActionButtonView, parent); 45920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mScrapActionButtonView == null) { 46020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mScrapActionButtonView = v; 46120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 46220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mStrictWidthLimit) { 46320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int cells = ActionMenuView.measureChildForCells(v, 46420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellSize, cellsRemaining, querySpec, 0); 46520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns cellsRemaining -= cells; 46620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (cells == 0) { 46720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns isAction = false; 46820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 46920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 47020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns v.measure(querySpec, querySpec); 47120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 47220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int measuredWidth = v.getMeasuredWidth(); 47320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns widthLimit -= measuredWidth; 47420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (firstActionWidth == 0) { 47520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns firstActionWidth = measuredWidth; 47620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 47720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 47820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mStrictWidthLimit) { 47920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns isAction &= widthLimit >= 0; 48020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 48120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Did this push the entire first item past the limit? 48220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns isAction &= widthLimit + firstActionWidth > 0; 48320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 48420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 48520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 48620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (isAction && groupId != 0) { 48720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns seenGroups.put(groupId, true); 48820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else if (inGroup) { 48920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // We broke the width limit. Demote the whole group, they all overflow now. 49020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns seenGroups.put(groupId, false); 49120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int j = 0; j < i; j++) { 49220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuItemImpl areYouMyGroupie = visibleItems.get(j); 49320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (areYouMyGroupie.getGroupId() == groupId) { 49420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Give back the action slot 49549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (areYouMyGroupie.isActionButton()) maxActions++; 49620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns areYouMyGroupie.setIsActionButton(false); 49720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 49820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 49920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 50020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 50149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isAction) maxActions--; 50220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 50320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns item.setIsActionButton(isAction); 50449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 50549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Neither requires nor requests an action button. 50649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes item.setIsActionButton(false); 50720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 50820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 50920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 510bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 511bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 51220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 51320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 51420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns dismissPopupMenus(); 51520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onCloseMenu(menu, allMenusAreClosing); 516bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 517bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 51820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 51920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public Parcelable onSaveInstanceState() { 52020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SavedState state = new SavedState(); 52120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns state.openSubMenuId = mOpenSubMenuId; 52220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return state; 523bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 524bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 52520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 52620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onRestoreInstanceState(Parcelable state) { 52720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SavedState saved = (SavedState) state; 52820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (saved.openSubMenuId > 0) { 52920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns MenuItem item = mMenu.findItem(saved.openSubMenuId); 53020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (item != null) { 53120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); 53220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns onSubMenuSelected(subMenu); 53320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 53420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 535bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 536bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 537bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell @Override 53820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onSubUiVisibilityChanged(boolean isVisible) { 53920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (isVisible) { 54020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // Not a submenu, but treat it like one. 54120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onSubMenuSelected(null); 54220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } else { 54320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.close(false); 54420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 545bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 546bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 54749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setMenuView(ActionMenuView menuView) { 54849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mMenuView = menuView; 54949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes menuView.initialize(mMenu); 55049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 551bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 55249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private static class SavedState implements Parcelable { 55320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public int openSubMenuId; 554bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 55520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SavedState() { 55620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 557bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 55820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns SavedState(Parcel in) { 55920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns openSubMenuId = in.readInt(); 56020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 56120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 56220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 56320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public int describeContents() { 56420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return 0; 56520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 566bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 56720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 56820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void writeToParcel(Parcel dest, int flags) { 56920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns dest.writeInt(openSubMenuId); 570bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 57120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 57220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public static final Parcelable.Creator<SavedState> CREATOR 57320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns = new Parcelable.Creator<SavedState>() { 57420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public SavedState createFromParcel(Parcel in) { 57520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return new SavedState(in); 57620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 57720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 57820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public SavedState[] newArray(int size) { 57920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return new SavedState[size]; 58020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 58120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns }; 582bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 583bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 584469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes private class OverflowMenuButton extends TintImageView implements ActionMenuView.ActionMenuChildView { 5850517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes private final float[] mTempPts = new float[2]; 5860517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes 58720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public OverflowMenuButton(Context context) { 58820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super(context, null, R.attr.actionOverflowButtonStyle); 58920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 59020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setClickable(true); 59120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setFocusable(true); 59220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setVisibility(VISIBLE); 59320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setEnabled(true); 5940517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes 59549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setOnTouchListener(new ListPopupWindow.ForwardingListener(this) { 59649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 59749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public ListPopupWindow getPopup() { 59849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOverflowPopup == null) { 59949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return null; 60049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 60149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mOverflowPopup.getPopup(); 60349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 60449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 60649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean onForwardingStarted() { 60749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes showOverflowMenu(); 60849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return true; 60949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 61049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 61249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean onForwardingStopped() { 61349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Displaying the popup occurs asynchronously, so wait for 61449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // the runnable to finish before deciding whether to stop 61549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // forwarding. 61649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mPostedOpenRunnable != null) { 61749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 61849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 61949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 62049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes hideOverflowMenu(); 62149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return true; 62249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 62349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }); 62420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 62520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 62620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 62720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean performClick() { 62820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (super.performClick()) { 62920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 63020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 63120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 63220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns playSoundEffect(SoundEffectConstants.CLICK); 63320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns showOverflowMenu(); 63420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return true; 63520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 63620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 63749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 63820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean needsDividerBefore() { 63920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 64020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 64120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 64249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 64320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean needsDividerAfter() { 64420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 64520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 646ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes 647ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes @Override 6480517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes protected boolean setFrame(int l, int t, int r, int b) { 6490517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes final boolean changed = super.setFrame(l, t, r, b); 650ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes 651ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes // Set up the hotspot bounds to be centered on the image. 652ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes final Drawable d = getDrawable(); 653ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes final Drawable bg = getBackground(); 654ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes if (d != null && bg != null) { 6550517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes final float[] pts = mTempPts; 6560517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes pts[0] = d.getBounds().centerX(); 6570517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes getImageMatrix().mapPoints(pts); 6580517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes final int offset = (int) pts[0] - getWidth() / 2; 6590517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes DrawableCompat.setHotspotBounds(bg, offset, 0, getWidth() + offset, getHeight()); 660ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes } 6610517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes 6620517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes return changed; 663ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes } 664bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 665bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 66620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private class OverflowPopup extends MenuPopupHelper { 667bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 66820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public OverflowPopup(Context context, MenuBuilder menu, View anchorView, 66920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns boolean overflowOnly) { 67049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(context, menu, anchorView, overflowOnly, R.attr.actionOverflowMenuStyle); 67149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setGravity(GravityCompat.END); 67220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setCallback(mPopupPresenterCallback); 67320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 674bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 67520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 67620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onDismiss() { 67720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns super.onDismiss(); 67820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.close(); 67920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowPopup = null; 68020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 681bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 682bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 68349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class ActionButtonSubmenu extends MenuPopupHelper { 68449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private SubMenuBuilder mSubMenu; 68549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 68649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { 68749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(context, subMenu, null, false, 68849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes R.attr.actionOverflowMenuStyle); 68949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mSubMenu = subMenu; 69049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 69149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MenuItemImpl item = (MenuItemImpl) subMenu.getItem(); 69249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!item.isActionButton()) { 69349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Give a reasonable anchor to nested submenus. 69449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton); 69549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 69620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 69720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns setCallback(mPopupPresenterCallback); 69849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 69949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean preserveIconSpacing = false; 70049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = subMenu.size(); 70149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 70249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MenuItem childItem = subMenu.getItem(i); 70349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childItem.isVisible() && childItem.getIcon() != null) { 70449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes preserveIconSpacing = true; 70549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 70649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 70749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 70849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setForceShowIcon(preserveIconSpacing); 70920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 71020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 71120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 71249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onDismiss() { 71349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onDismiss(); 71420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mActionButtonPopup = null; 71520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOpenSubMenuId = 0; 71620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 717bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 718bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 71949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class PopupPresenterCallback implements Callback { 72020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 72120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 72220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public boolean onOpenSubMenu(MenuBuilder subMenu) { 72349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (subMenu == null) return false; 72420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 72520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); 72649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final Callback cb = getCallback(); 72749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return cb != null ? cb.onOpenSubMenu(subMenu) : false; 72820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 729bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 73020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns @Override 73120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 73220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (menu instanceof SubMenuBuilder) { 73320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((SubMenuBuilder) menu).getRootMenu().close(false); 73420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 73549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final Callback cb = getCallback(); 73649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (cb != null) { 73749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes cb.onCloseMenu(menu, allMenusAreClosing); 73849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 73920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 740bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 741bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 74220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private class OpenOverflowRunnable implements Runnable { 74320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private OverflowPopup mPopup; 74420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 74520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public OpenOverflowRunnable(OverflowPopup popup) { 74620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPopup = popup; 74720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 74820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 74920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns public void run() { 75020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mMenu.changeMenuMode(); 75120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final View menuView = (View) mMenuView; 75220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) { 75320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mOverflowPopup = mPopup; 75420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 75520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mPostedOpenRunnable = null; 75620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 757bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell } 75849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 75949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private class ActionMenuPopupCallback extends ActionMenuItemView.PopupCallback { 76049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 76149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public ListPopupWindow getPopup() { 76249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null; 76349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 76449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 765bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell} 766