MenuBuilder.java revision 07a07ce59efb770e9fb9ca53a0133e5e64a63bbc
1bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell// Copyright 2012 Google Inc. All Rights Reserved. 2bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 3da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownpackage android.support.v7.internal.view.menu; 4bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 5bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.ComponentName; 6bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Context; 7bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Intent; 8ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport android.content.pm.PackageManager; 9ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport android.content.pm.ResolveInfo; 10ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport android.content.res.Configuration; 11ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport android.content.res.Resources; 12bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.graphics.drawable.Drawable; 13ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport android.os.Bundle; 14ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport android.os.Parcelable; 1530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.support.v4.view.MenuItemCompat; 16da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R; 1730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.support.v4.view.ActionProvider; 1830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.support.v4.internal.view.SupportMenu; 1930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.support.v4.internal.view.SupportMenuItem; 20ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport android.util.SparseArray; 21ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport android.view.ContextMenu; 22ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport android.view.KeyCharacterMap; 23bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.KeyEvent; 2430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem; 2530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.SubMenu; 26bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View; 27bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 28ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport java.lang.ref.WeakReference; 29bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport java.util.ArrayList; 30ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport java.util.List; 31ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewaniimport java.util.concurrent.CopyOnWriteArrayList; 32bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 33bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/** 3430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell * Implementation of the {@link android.support.v4.internal.view.SupportMenu} interface for creating a 35ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * standard menu UI. 36bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */ 3730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellpublic class MenuBuilder implements SupportMenu { 3820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 39ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private static final String TAG = "MenuBuilder"; 40ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 41ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private static final String PRESENTER_KEY = "android:menu:presenters"; 42ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private static final String ACTION_VIEW_STATES_KEY = "android:menu:actionviewstates"; 43ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private static final String EXPANDED_ACTION_VIEW_ID = "android:menu:expandedactionview"; 44ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns private static final int[] sCategoryToOrder = new int[]{ 46ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1, /* No category */ 47ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4, /* CONTAINER */ 48ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 5, /* SYSTEM */ 49ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 3, /* SECONDARY */ 50ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 2, /* ALTERNATIVE */ 51ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 0, /* SELECTED_ALTERNATIVE */ 52ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani }; 53ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 54ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private final Context mContext; 5520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 56ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private final Resources mResources; 57ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 58ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 5920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Whether the shortcuts should be qwerty-accessible. Use isQwertyMode() instead of accessing 6020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * this directly. 61ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 62ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private boolean mQwertyMode; 63ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 64ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 6520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Whether the shortcuts should be visible on menus. Use isShortcutsVisible() instead of 6620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * accessing this directly. 67ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 68ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private boolean mShortcutsVisible; 69ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 70ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 7120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Callback that will receive the various menu-related events generated by this class. Use 7220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * getCallback to get a reference to the callback. 73ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 74ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private Callback mCallback; 75ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 7620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 7720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Contains all of the items for this menu 7820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 79ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private ArrayList<MenuItemImpl> mItems; 80ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 8120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 8220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Contains only the items that are currently visible. This will be created/refreshed from 8320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * {@link #getVisibleItems()} 8420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 85ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private ArrayList<MenuItemImpl> mVisibleItems; 8620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 87ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 88ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Whether or not the items (or any one item's shown state) has changed since it was last 89ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * fetched from {@link #getVisibleItems()} 90ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 91ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private boolean mIsVisibleItemsStale; 92ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 93ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 94ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Contains only the items that should appear in the Action Bar, if present. 95ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 96ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private ArrayList<MenuItemImpl> mActionItems; 9720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 98ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 99ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Contains items that should NOT appear in the Action Bar, if present. 100ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 101ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private ArrayList<MenuItemImpl> mNonActionItems; 102ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 103ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 10420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Whether or not the items (or any one item's action state) has changed since it was last 10520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * fetched. 106ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 107ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private boolean mIsActionItemsStale; 108ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 109ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 110ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Default value for how added items should show in the action list. 111ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 11230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell private int mDefaultShowAsAction = SupportMenuItem.SHOW_AS_ACTION_NEVER; 113ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 114ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 11520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Current use case is Context Menus: As Views populate the context menu, each one has extra 11620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * information that should be passed along. This is the current menu info that should be set on 11720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * all items added to this menu. 118ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 119ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private ContextMenu.ContextMenuInfo mCurrentMenuInfo; 120ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 12120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 12220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Header title for menu types that have a header (context and submenus) 12320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 124ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani CharSequence mHeaderTitle; 12520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 12620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 12720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Header icon for menu types that have a header and support icons (context) 12820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 129ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani Drawable mHeaderIcon; 13020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 13120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns /** 13220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Header custom view for menu types that have a header and support custom views (context) 13320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 134ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani View mHeaderView; 135ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 136ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 13720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Prevents onItemsChanged from doing its junk, useful for batching commands that may 13820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * individually call onItemsChanged. 139ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 140ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private boolean mPreventDispatchingItemsChanged = false; 14120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 142ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private boolean mItemsChangedWhileDispatchPrevented = false; 143ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 144ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private boolean mOptionalIconsVisible = false; 145ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 146ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private boolean mIsClosing = false; 147ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 148ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private ArrayList<MenuItemImpl> mTempShortcutItemList = new ArrayList<MenuItemImpl>(); 149ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 150ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private CopyOnWriteArrayList<WeakReference<MenuPresenter>> mPresenters = 151ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani new CopyOnWriteArrayList<WeakReference<MenuPresenter>>(); 152ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 153ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 154ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Currently expanded menu item; must be collapsed when we clear. 155ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 156ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private MenuItemImpl mExpandedItem; 157ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 158ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 159ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Called by menu to notify of close and selection changes. 160ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 161ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public interface Callback { 16220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 163ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 164ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Called when a menu item is selected. 16520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 166ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param menu The menu that is the parent of the item 167ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param item The menu item that is selected 168ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @return whether the menu item selection was handled 169ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 170ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item); 171ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 172ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 173ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Called when the mode of the menu changes (for example, from icon to expanded). 174ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 175ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param menu the menu that has changed modes 176ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 177ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void onMenuModeChange(MenuBuilder menu); 178ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 179ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 180ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 181ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Called by menu items to execute their associated action 182ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 183ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public interface ItemInvoker { 18420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 185ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean invokeItem(MenuItemImpl item); 186ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 187ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 188ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuBuilder(Context context) { 189ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mContext = context; 190ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mResources = context.getResources(); 191ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 192ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mItems = new ArrayList<MenuItemImpl>(); 193ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 194ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mVisibleItems = new ArrayList<MenuItemImpl>(); 195ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsVisibleItemsStale = true; 196ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 197ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mActionItems = new ArrayList<MenuItemImpl>(); 198ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mNonActionItems = new ArrayList<MenuItemImpl>(); 199ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsActionItemsStale = true; 200ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 201ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani setShortcutsVisibleInner(true); 202ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 203ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 204ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuBuilder setDefaultShowAsAction(int defaultShowAsAction) { 205ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mDefaultShowAsAction = defaultShowAsAction; 206ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return this; 207ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 208ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 209ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 21020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Add a presenter to this menu. This will only hold a WeakReference; you do not need to 21120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * explicitly remove a presenter, but you can using {@link #removeMenuPresenter(MenuPresenter)}. 212ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 213ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param presenter The presenter to add 214ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 215ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void addMenuPresenter(MenuPresenter presenter) { 216ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.add(new WeakReference<MenuPresenter>(presenter)); 217ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani presenter.initForMenu(mContext, this); 218ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsActionItemsStale = true; 219ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 220ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 221ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 22220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Remove a presenter from this menu. That presenter will no longer receive notifications of 22320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * updates to this menu's data. 224ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 225ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param presenter The presenter to remove 226ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 227ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void removeMenuPresenter(MenuPresenter presenter) { 228ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (WeakReference<MenuPresenter> ref : mPresenters) { 229ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuPresenter item = ref.get(); 230ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item == null || item == presenter) { 231ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.remove(ref); 232ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 233ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 234ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 235ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 236ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private void dispatchPresenterUpdate(boolean cleared) { 23720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mPresenters.isEmpty()) { 23820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return; 23920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 240ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 241ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani stopDispatchingItemsChanged(); 242ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (WeakReference<MenuPresenter> ref : mPresenters) { 243ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuPresenter presenter = ref.get(); 244ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (presenter == null) { 245ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.remove(ref); 246ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 247ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani presenter.updateMenuView(cleared); 248ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 249ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 250ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani startDispatchingItemsChanged(); 251ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 252ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 253ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private boolean dispatchSubMenuSelected(SubMenuBuilder subMenu) { 25420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mPresenters.isEmpty()) { 25520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 25620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 257ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 258ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean result = false; 259ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 260ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (WeakReference<MenuPresenter> ref : mPresenters) { 261ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuPresenter presenter = ref.get(); 262ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (presenter == null) { 263ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.remove(ref); 264ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else if (!result) { 265ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani result = presenter.onSubMenuSelected(subMenu); 266ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 267ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 268ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return result; 269ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 270ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 271ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private void dispatchSaveInstanceState(Bundle outState) { 27220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mPresenters.isEmpty()) { 27320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return; 27420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 275ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 276ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani SparseArray<Parcelable> presenterStates = new SparseArray<Parcelable>(); 277ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 278ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (WeakReference<MenuPresenter> ref : mPresenters) { 279ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuPresenter presenter = ref.get(); 280ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (presenter == null) { 281ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.remove(ref); 282ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 283ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int id = presenter.getId(); 284ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (id > 0) { 285ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final Parcelable state = presenter.onSaveInstanceState(); 286ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (state != null) { 287ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani presenterStates.put(id, state); 288ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 289ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 290ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 291ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 292ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 293ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani outState.putSparseParcelableArray(PRESENTER_KEY, presenterStates); 294ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 295ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 296ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private void dispatchRestoreInstanceState(Bundle state) { 297ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani SparseArray<Parcelable> presenterStates = state.getSparseParcelableArray(PRESENTER_KEY); 298ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 29920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (presenterStates == null || mPresenters.isEmpty()) { 30020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return; 30120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 302ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 303ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (WeakReference<MenuPresenter> ref : mPresenters) { 304ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuPresenter presenter = ref.get(); 305ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (presenter == null) { 306ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.remove(ref); 307ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 308ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int id = presenter.getId(); 309ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (id > 0) { 310ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani Parcelable parcel = presenterStates.get(id); 311ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (parcel != null) { 312ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani presenter.onRestoreInstanceState(parcel); 313ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 314ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 315ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 316ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 317ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 318ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 319ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void savePresenterStates(Bundle outState) { 320ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani dispatchSaveInstanceState(outState); 321ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 322ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 323ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void restorePresenterStates(Bundle state) { 324ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani dispatchRestoreInstanceState(state); 325ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 326ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 327ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void saveActionViewStates(Bundle outStates) { 328ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani SparseArray<Parcelable> viewStates = null; 329ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 330ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int itemCount = size(); 331ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < itemCount; i++) { 332ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuItem item = getItem(i); 33330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell final View v = MenuItemCompat.getActionView(item); 334ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (v != null && v.getId() != View.NO_ID) { 335ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (viewStates == null) { 336ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani viewStates = new SparseArray<Parcelable>(); 337ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 338ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani v.saveHierarchyState(viewStates); 33930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell if (MenuItemCompat.isActionViewExpanded(item)) { 340ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani outStates.putInt(EXPANDED_ACTION_VIEW_ID, item.getItemId()); 341ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 342ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 343ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.hasSubMenu()) { 344ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); 345ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani subMenu.saveActionViewStates(outStates); 346ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 347ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 348ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 349ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (viewStates != null) { 350ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani outStates.putSparseParcelableArray(getActionViewStatesKey(), viewStates); 351ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 352ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 353ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 354ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void restoreActionViewStates(Bundle states) { 355ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (states == null) { 356ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return; 357ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 358ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 359ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani SparseArray<Parcelable> viewStates = states.getSparseParcelableArray( 360ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani getActionViewStatesKey()); 361ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 362ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int itemCount = size(); 363ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < itemCount; i++) { 364ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuItem item = getItem(i); 36530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell final View v = MenuItemCompat.getActionView(item); 366ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (v != null && v.getId() != View.NO_ID) { 367ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani v.restoreHierarchyState(viewStates); 368ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 369ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.hasSubMenu()) { 370ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); 371ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani subMenu.restoreActionViewStates(states); 372ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 373ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 374ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 375ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int expandedId = states.getInt(EXPANDED_ACTION_VIEW_ID); 376ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (expandedId > 0) { 377ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItem itemToExpand = findItem(expandedId); 378ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (itemToExpand != null) { 37930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell MenuItemCompat.expandActionView(itemToExpand); 380ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 381ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 382ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 383ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 384ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani protected String getActionViewStatesKey() { 385ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return ACTION_VIEW_STATES_KEY; 386ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 387ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 388ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void setCallback(Callback cb) { 389ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mCallback = cb; 390ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 391ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 392ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 393ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Adds an item to the menu. The other add methods funnel to this. 394ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 395ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private MenuItem addInternal(int group, int id, int categoryOrder, CharSequence title) { 396ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int ordering = getOrdering(categoryOrder); 397ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 398ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuItemImpl item = new MenuItemImpl(this, group, id, categoryOrder, 399ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani ordering, title, mDefaultShowAsAction); 400ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 401ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (mCurrentMenuInfo != null) { 402ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Pass along the current menu info 403ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani item.setMenuInfo(mCurrentMenuInfo); 404ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 405ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 406ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mItems.add(findInsertIndex(mItems, ordering), item); 407ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(true); 408ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 409ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return item; 410ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 411ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4126e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 413ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuItem add(CharSequence title) { 414ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return addInternal(0, 0, 0, title); 415ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 416ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4176e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 418ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuItem add(int titleRes) { 419ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return addInternal(0, 0, 0, mResources.getString(titleRes)); 420ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 421ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4226e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 423ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuItem add(int group, int id, int categoryOrder, CharSequence title) { 424ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return addInternal(group, id, categoryOrder, title); 425ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 426ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4276e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 428ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuItem add(int group, int id, int categoryOrder, int title) { 429ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return addInternal(group, id, categoryOrder, mResources.getString(title)); 430ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 431ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4326e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 433ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public SubMenu addSubMenu(CharSequence title) { 434ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return addSubMenu(0, 0, 0, title); 435ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 436ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4376e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 438ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public SubMenu addSubMenu(int titleRes) { 439ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return addSubMenu(0, 0, 0, mResources.getString(titleRes)); 440ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 441ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4426e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 443ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public SubMenu addSubMenu(int group, int id, int categoryOrder, CharSequence title) { 444ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuItemImpl item = (MenuItemImpl) addInternal(group, id, categoryOrder, title); 445ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final SubMenuBuilder subMenu = new SubMenuBuilder(mContext, this, item); 446ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani item.setSubMenu(subMenu); 447ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 448ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return subMenu; 449ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 450ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4516e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 452ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public SubMenu addSubMenu(int group, int id, int categoryOrder, int title) { 453ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return addSubMenu(group, id, categoryOrder, mResources.getString(title)); 454ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 455ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4566e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 457ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public int addIntentOptions(int group, int id, int categoryOrder, ComponentName caller, 45820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) { 459ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani PackageManager pm = mContext.getPackageManager(); 460ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final List<ResolveInfo> lri = 461ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani pm.queryIntentActivityOptions(caller, specifics, intent, 0); 462ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int N = lri != null ? lri.size() : 0; 463ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 464ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if ((flags & FLAG_APPEND_TO_GROUP) == 0) { 465ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani removeGroup(group); 466ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 467ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 46820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns for (int i = 0; i < N; i++) { 469ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final ResolveInfo ri = lri.get(i); 470ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani Intent rintent = new Intent( 471ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani ri.specificIndex < 0 ? intent : specifics[ri.specificIndex]); 472ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani rintent.setComponent(new ComponentName( 473ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani ri.activityInfo.applicationInfo.packageName, 474ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani ri.activityInfo.name)); 475ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuItem item = add(group, id, categoryOrder, ri.loadLabel(pm)) 476ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani .setIcon(ri.loadIcon(pm)) 477ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani .setIntent(rintent); 478ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (outSpecificItems != null && ri.specificIndex >= 0) { 479ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani outSpecificItems[ri.specificIndex] = item; 480ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 481ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 482ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 483ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return N; 484ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 485ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4866e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 487ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void removeItem(int id) { 488ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani removeItemAtInt(findItemIndex(id), true); 489ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 490ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 4916e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 492ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void removeGroup(int group) { 493ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int i = findGroupIndex(group); 494ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 495ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (i >= 0) { 496ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int maxRemovable = mItems.size() - i; 497ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani int numRemoved = 0; 498ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani while ((numRemoved++ < maxRemovable) && (mItems.get(i).getGroupId() == group)) { 499ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Don't force update for each one, this method will do it at the end 500ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani removeItemAtInt(i, false); 501ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 502ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 503ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Notify menu views 504ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(true); 505ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 506ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 507ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 508ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 50920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Remove the item at the given index and optionally forces menu views to update. 510ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 51120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param index The index of the item to be removed. If this index is 51220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * invalid an exception is thrown. 51320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param updateChildrenOnMenuViews Whether to force update on menu views. Please make sure you 51420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * eventually call this after your batch of removals. 515ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 516ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private void removeItemAtInt(int index, boolean updateChildrenOnMenuViews) { 51720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if ((index < 0) || (index >= mItems.size())) { 51820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return; 51920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 520ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 521ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mItems.remove(index); 522ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 52320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (updateChildrenOnMenuViews) { 52420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns onItemsChanged(true); 52520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 526ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 527ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 528ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void removeItemAt(int index) { 529ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani removeItemAtInt(index, true); 530ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 531ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 532ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void clearAll() { 533ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPreventDispatchingItemsChanged = true; 534ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani clear(); 535ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani clearHeader(); 536ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPreventDispatchingItemsChanged = false; 537ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mItemsChangedWhileDispatchPrevented = false; 538ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(true); 539ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 540ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 5416e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 542ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void clear() { 543ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (mExpandedItem != null) { 544ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani collapseItemActionView(mExpandedItem); 545ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 546ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mItems.clear(); 547ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 548ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(true); 549ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 550ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 551ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani void setExclusiveItemChecked(MenuItem item) { 552ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int group = item.getGroupId(); 553ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 554ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int N = mItems.size(); 555ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < N; i++) { 556ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl curItem = mItems.get(i); 557ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (curItem.getGroupId() == group) { 55820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!curItem.isExclusiveCheckable()) { 55920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns continue; 56020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 56120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!curItem.isCheckable()) { 56220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns continue; 56320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 564ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 565ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Check the item meant to be checked, uncheck the others (that are in the group) 566ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani curItem.setCheckedInt(curItem == item); 567ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 568ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 569ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 570ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 5716e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 572ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void setGroupCheckable(int group, boolean checkable, boolean exclusive) { 573ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int N = mItems.size(); 574ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 575ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < N; i++) { 576ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item = mItems.get(i); 577ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.getGroupId() == group) { 578ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani item.setExclusiveCheckable(exclusive); 579ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani item.setCheckable(checkable); 580ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 581ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 582ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 583ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 5846e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 585ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void setGroupVisible(int group, boolean visible) { 586ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int N = mItems.size(); 587ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 58820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // We handle the notification of items being changed ourselves, so we use setVisibleInt 58920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // rather than setVisible and at the end notify of items being changed 590ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 591ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean changedAtLeastOneItem = false; 592ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < N; i++) { 593ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item = mItems.get(i); 594ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.getGroupId() == group) { 59520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (item.setVisibleInt(visible)) { 59620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns changedAtLeastOneItem = true; 59720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 598ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 599ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 600ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 60120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (changedAtLeastOneItem) { 60220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns onItemsChanged(true); 60320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 604ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 605ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 6066e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 607ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void setGroupEnabled(int group, boolean enabled) { 608ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int N = mItems.size(); 609ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 610ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < N; i++) { 611ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item = mItems.get(i); 612ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.getGroupId() == group) { 613ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani item.setEnabled(enabled); 614ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 615ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 616ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 617ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 6186e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 619ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean hasVisibleItems() { 620ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int size = size(); 621bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 622ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < size; i++) { 623ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item = mItems.get(i); 624ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.isVisible()) { 625ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return true; 626ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 627ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 628bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 629ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return false; 630ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 631bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 6326e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 633ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuItem findItem(int id) { 634ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int size = size(); 635ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < size; i++) { 636ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item = mItems.get(i); 637ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.getItemId() == id) { 638ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return item; 639ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else if (item.hasSubMenu()) { 640ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItem possibleItem = item.getSubMenu().findItem(id); 641bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 642ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (possibleItem != null) { 643ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return possibleItem; 644ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 645ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 646ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 647bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 648ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return null; 649ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 650bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 651ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public int findItemIndex(int id) { 652ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int size = size(); 653bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 654ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < size; i++) { 655ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item = mItems.get(i); 656ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.getItemId() == id) { 657ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return i; 658ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 659ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 660bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 661ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return -1; 662ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 663bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 664ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public int findGroupIndex(int group) { 665ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return findGroupIndex(group, 0); 666ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 667bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 668ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public int findGroupIndex(int group, int start) { 669ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int size = size(); 670bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell 671ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (start < 0) { 672ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani start = 0; 673ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 674ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 675ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = start; i < size; i++) { 676ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuItemImpl item = mItems.get(i); 677ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 678ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.getGroupId() == group) { 679ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return i; 680ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 681ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 682ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 683ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return -1; 684ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 685ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 6866e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 687ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public int size() { 688ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mItems.size(); 689ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 690ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 6916e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 692ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuItem getItem(int index) { 693ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mItems.get(index); 694ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 695ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 6966e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 697ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean isShortcutKey(int keyCode, KeyEvent event) { 698ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return findItemWithShortcutForKey(keyCode, event) != null; 699ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 700ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 7016e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 702ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void setQwertyMode(boolean isQwerty) { 703ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mQwertyMode = isQwerty; 704ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 705ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(false); 706ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 707ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 708ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 70920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Returns the ordering across all items. This will grab the category from the upper bits, find 71020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * out how to order the category with respect to other categories, and combine it with the lower 71120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * bits. 712ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 71320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param categoryOrder The category order for a particular item (if it has not been or/add with 71420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * a category, the default category is assumed). 71520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return An ordering integer that can be used to order this item across all the items (even 71620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * from other categories). 717ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 718ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private static int getOrdering(int categoryOrder) { 719ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int index = (categoryOrder & CATEGORY_MASK) >> CATEGORY_SHIFT; 720ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 721ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (index < 0 || index >= sCategoryToOrder.length) { 722ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani throw new IllegalArgumentException("order does not contain a valid category."); 723ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 724ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 725ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return (sCategoryToOrder[index] << CATEGORY_SHIFT) | (categoryOrder & USER_MASK); 726ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 727b17b7b75ce2989f50a12ef00f198276e30b9c780Trevor Johns 728b17b7b75ce2989f50a12ef00f198276e30b9c780Trevor Johns /** 729ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @return whether the menu shortcuts are in qwerty mode or not 730b17b7b75ce2989f50a12ef00f198276e30b9c780Trevor Johns */ 731ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean isQwertyMode() { 732ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mQwertyMode; 733ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 734b17b7b75ce2989f50a12ef00f198276e30b9c780Trevor Johns 735b17b7b75ce2989f50a12ef00f198276e30b9c780Trevor Johns /** 73620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets whether the shortcuts should be visible on menus. Devices without hardware key input 73720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * will never make shortcuts visible even if this method is passed 'true'. 738b17b7b75ce2989f50a12ef00f198276e30b9c780Trevor Johns * 73920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param shortcutsVisible Whether shortcuts should be visible (if true and a menu item does not 74020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * have a shortcut defined, that item will still NOT show a shortcut) 741ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 742ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void setShortcutsVisible(boolean shortcutsVisible) { 74320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mShortcutsVisible == shortcutsVisible) { 74420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return; 74520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 746ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 747ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani setShortcutsVisibleInner(shortcutsVisible); 748ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(false); 749ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 750ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 751ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private void setShortcutsVisibleInner(boolean shortcutsVisible) { 752ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mShortcutsVisible = shortcutsVisible 753ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani && mResources.getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS 75407a07ce59efb770e9fb9ca53a0133e5e64a63bbcChris Banes && mResources.getBoolean(R.bool.abc_config_showMenuShortcutsWhenKeyboardPresent); 755ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 756ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 757ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 758ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @return Whether shortcuts should be visible on menus. 759ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 760ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean isShortcutsVisible() { 761ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mShortcutsVisible; 762ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 763ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 764ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani Resources getResources() { 765ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mResources; 766ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 767ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 768ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public Context getContext() { 769ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mContext; 770ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 771ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 772ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean dispatchMenuItemSelected(MenuBuilder menu, MenuItem item) { 773ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mCallback != null && mCallback.onMenuItemSelected(menu, item); 774ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 775ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 776ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 777ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Dispatch a mode change event to this menu's callback. 778ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 779ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void changeMenuMode() { 780ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (mCallback != null) { 781ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mCallback.onMenuModeChange(this); 782ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 783ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 784ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 785ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private static int findInsertIndex(ArrayList<MenuItemImpl> items, int ordering) { 786ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = items.size() - 1; i >= 0; i--) { 787ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item = items.get(i); 788ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.getOrdering() <= ordering) { 789ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return i + 1; 790ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 791ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 792ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 793ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return 0; 794ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 795ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 7966e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 797ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean performShortcut(int keyCode, KeyEvent event, int flags) { 798ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuItemImpl item = findItemWithShortcutForKey(keyCode, event); 799ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 800ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean handled = false; 801ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 802ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item != null) { 803ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani handled = performItemAction(item, flags); 804ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 805ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 806ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if ((flags & FLAG_ALWAYS_PERFORM_CLOSE) != 0) { 807ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani close(true); 808ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 809ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 810ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return handled; 811ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 812ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 813ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /* 814ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * This function will return all the menu and sub-menu items that can 815ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * be directly (the shortcut directly corresponds) and indirectly 816ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * (the ALT-enabled char corresponds to the shortcut) associated 817ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * with the keyCode. 818ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 8196e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @SuppressWarnings("deprecation") 820ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani void findItemsWithShortcutForKey(List<MenuItemImpl> items, int keyCode, KeyEvent event) { 821ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final boolean qwerty = isQwertyMode(); 822ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int metaState = event.getMetaState(); 823ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData(); 824ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Get the chars associated with the keyCode (i.e using any chording combo) 825ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final boolean isKeyCodeMapped = event.getKeyData(possibleChars); 826ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // The delete key is not mapped to '\b' so we treat it specially 827ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (!isKeyCodeMapped && (keyCode != KeyEvent.KEYCODE_DEL)) { 828ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return; 829ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 830ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 831ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Look for an item whose shortcut is this key. 832ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int N = mItems.size(); 833ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < N; i++) { 834ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item = mItems.get(i); 835ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.hasSubMenu()) { 83620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ((MenuBuilder) item.getSubMenu()) 83720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns .findItemsWithShortcutForKey(items, keyCode, event); 838ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 83920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final char shortcutChar = qwerty ? item.getAlphabeticShortcut() 84020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns : item.getNumericShortcut(); 841ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (((metaState & (KeyEvent.META_SHIFT_ON | KeyEvent.META_SYM_ON)) == 0) && 842ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani (shortcutChar != 0) && 843ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani (shortcutChar == possibleChars.meta[0] 844ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani || shortcutChar == possibleChars.meta[2] 845ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani || (qwerty && shortcutChar == '\b' && 846ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani keyCode == KeyEvent.KEYCODE_DEL)) && 847ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani item.isEnabled()) { 848ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani items.add(item); 849ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 850ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 851ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 852ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 853ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /* 854ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * We want to return the menu item associated with the key, but if there is no 855ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * ambiguity (i.e. there is only one menu item corresponding to the key) we want 856ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * to return it even if it's not an exact match; this allow the user to 857ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * _not_ use the ALT key for example, making the use of shortcuts slightly more 858ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * user-friendly. An example is on the G1, '!' and '1' are on the same key, and 859ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * in Gmail, Menu+1 will trigger Menu+! (the actual shortcut). 860ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 861ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * On the other hand, if two (or more) shortcuts corresponds to the same key, 862ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * we have to only return the exact match. 863ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 8646e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @SuppressWarnings("deprecation") 865ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl findItemWithShortcutForKey(int keyCode, KeyEvent event) { 866ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Get all items that can be associated directly or indirectly with the keyCode 867ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani ArrayList<MenuItemImpl> items = mTempShortcutItemList; 868ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani items.clear(); 869ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani findItemsWithShortcutForKey(items, keyCode, event); 870ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 871ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (items.isEmpty()) { 872ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return null; 873ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 874ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 875ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int metaState = event.getMetaState(); 876ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final KeyCharacterMap.KeyData possibleChars = new KeyCharacterMap.KeyData(); 877ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Get the chars associated with the keyCode (i.e using any chording combo) 878ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani event.getKeyData(possibleChars); 879ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 880ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // If we have only one element, we can safely returns it 881ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int size = items.size(); 882ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (size == 1) { 883ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return items.get(0); 884ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 885ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 886ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final boolean qwerty = isQwertyMode(); 887ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // If we found more than one item associated with the key, 888ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // we have to return the exact match 889ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < size; i++) { 890ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuItemImpl item = items.get(i); 891ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final char shortcutChar = qwerty ? item.getAlphabeticShortcut() : 892ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani item.getNumericShortcut(); 893ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if ((shortcutChar == possibleChars.meta[0] && 894ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani (metaState & KeyEvent.META_ALT_ON) == 0) 895ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani || (shortcutChar == possibleChars.meta[2] && 896ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani (metaState & KeyEvent.META_ALT_ON) != 0) 897ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani || (qwerty && shortcutChar == '\b' && 898ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani keyCode == KeyEvent.KEYCODE_DEL)) { 899ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return item; 900ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 901ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 902ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return null; 903ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 904ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 9056e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 906ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean performIdentifierAction(int id, int flags) { 907ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Look for an item whose identifier is the id. 908ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return performItemAction(findItem(id), flags); 909ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 910ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 911ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean performItemAction(MenuItem item, int flags) { 912ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl itemImpl = (MenuItemImpl) item; 913ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 914ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (itemImpl == null || !itemImpl.isEnabled()) { 915ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return false; 916ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 917ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 918ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean invoked = itemImpl.invoke(); 919ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 92030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell final ActionProvider provider = itemImpl.getSupportActionProvider(); 921ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final boolean providerHasSubMenu = provider != null && provider.hasSubMenu(); 922ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (itemImpl.hasCollapsibleActionView()) { 923ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani invoked |= itemImpl.expandActionView(); 92420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (invoked) { 92520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns close(true); 92620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 927ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else if (itemImpl.hasSubMenu() || providerHasSubMenu) { 928ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani close(false); 929ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 930ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (!itemImpl.hasSubMenu()) { 931ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani itemImpl.setSubMenu(new SubMenuBuilder(getContext(), this, itemImpl)); 932ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 933ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 934ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final SubMenuBuilder subMenu = (SubMenuBuilder) itemImpl.getSubMenu(); 935ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (providerHasSubMenu) { 936ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani provider.onPrepareSubMenu(subMenu); 937ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 938ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani invoked |= dispatchSubMenuSelected(subMenu); 93920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!invoked) { 94020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns close(true); 94120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 942ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 943ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if ((flags & FLAG_PERFORM_NO_CLOSE) == 0) { 944ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani close(true); 945ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 946ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 947ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 948ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return invoked; 949ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 950ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 951ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 952ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Closes the visible menu. 953ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 95420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param allMenusAreClosing Whether the menus are completely closing (true), or whether there 95520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * is another menu coming in this menu's place (false). For example, 95620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * if the menu is closing because a sub menu is about to be shown, 95720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * <var>allMenusAreClosing</var> is false. 958ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 959ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final void close(boolean allMenusAreClosing) { 96020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mIsClosing) { 96120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return; 96220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 963ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 964ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsClosing = true; 965ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (WeakReference<MenuPresenter> ref : mPresenters) { 966ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuPresenter presenter = ref.get(); 967ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (presenter == null) { 968ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.remove(ref); 969ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 970ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani presenter.onCloseMenu(this, allMenusAreClosing); 971ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 972ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 973ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsClosing = false; 974ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 975ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 9766e6abe6eb358db4c3932752249c8ac61dd3dab21Jeff Brown @Override 977ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void close() { 978ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani close(true); 979ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 980ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 981ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 982ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Called when an item is added or removed. 983ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 98420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param structureChanged true if the menu structure changed, false if only item properties 98520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * changed. (Visibility is a structural property since it affects 98620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * layout.) 987ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 988ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani void onItemsChanged(boolean structureChanged) { 989ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (!mPreventDispatchingItemsChanged) { 990ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (structureChanged) { 991ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsVisibleItemsStale = true; 992ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsActionItemsStale = true; 993ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 994ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 995ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani dispatchPresenterUpdate(structureChanged); 996ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 997ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mItemsChangedWhileDispatchPrevented = true; 998ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 999ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1000ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1001ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 100220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Stop dispatching item changed events to presenters until {@link 100320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * #startDispatchingItemsChanged()} is called. Useful when many menu operations are going to be 100420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * performed as a batch. 1005ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1006ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void stopDispatchingItemsChanged() { 1007ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (!mPreventDispatchingItemsChanged) { 1008ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPreventDispatchingItemsChanged = true; 1009ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mItemsChangedWhileDispatchPrevented = false; 1010ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1011ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1012ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1013ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void startDispatchingItemsChanged() { 1014ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPreventDispatchingItemsChanged = false; 1015ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1016ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (mItemsChangedWhileDispatchPrevented) { 1017ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mItemsChangedWhileDispatchPrevented = false; 1018ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(true); 1019ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1020ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1021ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1022ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 1023ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Called by {@link MenuItemImpl} when its visible flag is changed. 102420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 1025ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param item The item that has gone through a visibility change. 1026b17b7b75ce2989f50a12ef00f198276e30b9c780Trevor Johns */ 1027ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani void onItemVisibleChanged(MenuItemImpl item) { 1028ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Notify of items being changed 1029ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsVisibleItemsStale = true; 1030ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(true); 1031ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1032ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1033ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 1034ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Called by {@link MenuItemImpl} when its action request status is changed. 103520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 1036ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param item The item that has gone through a change in action request status. 1037ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1038ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani void onItemActionRequestChanged(MenuItemImpl item) { 1039ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Notify of items being changed 1040ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsActionItemsStale = true; 1041ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(true); 1042ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1043ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1044ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani ArrayList<MenuItemImpl> getVisibleItems() { 104520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (!mIsVisibleItemsStale) { 104620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return mVisibleItems; 104720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 1048ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1049ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Refresh the visible items 1050ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mVisibleItems.clear(); 1051ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1052ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int itemsSize = mItems.size(); 1053ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item; 1054ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < itemsSize; i++) { 1055ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani item = mItems.get(i); 105620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (item.isVisible()) { 105720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns mVisibleItems.add(item); 105820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 1059ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1060ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1061ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsVisibleItemsStale = false; 1062ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsActionItemsStale = true; 1063ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1064ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mVisibleItems; 1065ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1066ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1067ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 1068ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * This method determines which menu items get to be 'action items' that will appear 1069ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * in an action bar and which items should be 'overflow items' in a secondary menu. 1070ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * The rules are as follows: 1071ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 1072ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * <p>Items are considered for inclusion in the order specified within the menu. 1073ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * There is a limit of mMaxActionItems as a total count, optionally including the overflow 1074ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * menu button itself. This is a soft limit; if an item shares a group ID with an item 1075ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * previously included as an action item, the new item will stay with its group and become 1076ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * an action item itself even if it breaks the max item count limit. This is done to 1077ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * limit the conceptual complexity of the items presented within an action bar. Only a few 1078ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * unrelated concepts should be presented to the user in this space, and groups are treated 1079ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * as a single concept. 1080ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 1081ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * <p>There is also a hard limit of consumed measurable space: mActionWidthLimit. This 1082ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * limit may be broken by a single item that exceeds the remaining space, but no further 1083ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * items may be added. If an item that is part of a group cannot fit within the remaining 1084ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * measured width, the entire group will be demoted to overflow. This is done to ensure room 1085ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * for navigation and other affordances in the action bar as well as reduce general UI clutter. 1086ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 1087ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * <p>The space freed by demoting a full group cannot be consumed by future menu items. 1088ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Once items begin to overflow, all future items become overflow items as well. This is 1089ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * to avoid inadvertent reordering that may break the app's intended design. 1090ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1091ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void flagActionItems() { 1092ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (!mIsActionItemsStale) { 1093ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return; 1094ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1095ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1096ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Presenters flag action items as needed. 1097ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean flagged = false; 1098ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (WeakReference<MenuPresenter> ref : mPresenters) { 1099ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuPresenter presenter = ref.get(); 1100ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (presenter == null) { 1101ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.remove(ref); 1102ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 1103ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani flagged |= presenter.flagActionItems(); 1104ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1105ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1106ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1107ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (flagged) { 1108ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mActionItems.clear(); 1109ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mNonActionItems.clear(); 1110ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani ArrayList<MenuItemImpl> visibleItems = getVisibleItems(); 1111ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final int itemsSize = visibleItems.size(); 1112ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (int i = 0; i < itemsSize; i++) { 1113ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani MenuItemImpl item = visibleItems.get(i); 1114ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (item.isActionButton()) { 1115ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mActionItems.add(item); 1116ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 1117ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mNonActionItems.add(item); 1118ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1119ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1120ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 1121ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Nobody flagged anything, everything is a non-action item. 1122ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // (This happens during a first pass with no action-item presenters.) 1123ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mActionItems.clear(); 1124ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mNonActionItems.clear(); 1125ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mNonActionItems.addAll(getVisibleItems()); 1126ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1127ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mIsActionItemsStale = false; 1128ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1129ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1130ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani ArrayList<MenuItemImpl> getActionItems() { 1131ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani flagActionItems(); 1132ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mActionItems; 1133ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1134ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1135ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani ArrayList<MenuItemImpl> getNonActionItems() { 1136ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani flagActionItems(); 1137ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mNonActionItems; 1138ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1139ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1140ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void clearHeader() { 1141ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderIcon = null; 1142ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderTitle = null; 1143ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderView = null; 1144ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1145ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(false); 1146ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1147ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1148ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani private void setHeaderInternal(final int titleRes, final CharSequence title, final int iconRes, 114920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final Drawable icon, final View view) { 1150ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final Resources r = getResources(); 1151ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1152ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (view != null) { 1153ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderView = view; 1154ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1155ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // If using a custom view, then the title and icon aren't used 1156ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderTitle = null; 1157ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderIcon = null; 1158ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else { 1159ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (titleRes > 0) { 1160ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderTitle = r.getText(titleRes); 1161ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else if (title != null) { 1162ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderTitle = title; 1163ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1164ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1165ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (iconRes > 0) { 1166ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderIcon = r.getDrawable(iconRes); 1167ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else if (icon != null) { 1168ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderIcon = icon; 1169ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1170ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1171ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // If using the title or icon, then a custom view isn't used 1172ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mHeaderView = null; 1173ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1174ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1175ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani // Notify of change 1176ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani onItemsChanged(false); 1177ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1178ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1179ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 118020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the header's title. This replaces the header view. Called by the builder-style methods 118120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * of subclasses. 1182ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 1183ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param title The new title. 1184ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @return This MenuBuilder so additional setters can be called. 1185ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1186ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani protected MenuBuilder setHeaderTitleInt(CharSequence title) { 1187ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani setHeaderInternal(0, title, 0, null, null); 1188ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return this; 1189ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1190ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1191ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 119220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the header's title. This replaces the header view. Called by the builder-style methods 119320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * of subclasses. 1194ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 1195ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param titleRes The new title (as a resource ID). 1196ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @return This MenuBuilder so additional setters can be called. 1197ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1198ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani protected MenuBuilder setHeaderTitleInt(int titleRes) { 1199ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani setHeaderInternal(titleRes, null, 0, null, null); 1200ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return this; 1201ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1202ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1203ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 120420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the header's icon. This replaces the header view. Called by the builder-style methods of 120520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * subclasses. 1206ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 1207ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param icon The new icon. 1208ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @return This MenuBuilder so additional setters can be called. 1209ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1210ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani protected MenuBuilder setHeaderIconInt(Drawable icon) { 1211ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani setHeaderInternal(0, null, 0, icon, null); 1212ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return this; 1213ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1214ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1215ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 121620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the header's icon. This replaces the header view. Called by the builder-style methods of 121720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * subclasses. 1218ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 1219ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param iconRes The new icon (as a resource ID). 1220ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @return This MenuBuilder so additional setters can be called. 1221ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1222ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani protected MenuBuilder setHeaderIconInt(int iconRes) { 1223ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani setHeaderInternal(0, null, iconRes, null, null); 1224ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return this; 1225ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1226ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1227ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 122820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the header's view. This replaces the title and icon. Called by the builder-style methods 122920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * of subclasses. 1230ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 1231ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param view The new view. 1232ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @return This MenuBuilder so additional setters can be called. 1233ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1234ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani protected MenuBuilder setHeaderViewInt(View view) { 1235ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani setHeaderInternal(0, null, 0, null, view); 1236ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return this; 1237ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1238ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1239ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public CharSequence getHeaderTitle() { 1240ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mHeaderTitle; 1241ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1242ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1243ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public Drawable getHeaderIcon() { 1244ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mHeaderIcon; 1245ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1246ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1247ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public View getHeaderView() { 1248ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mHeaderView; 1249ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1250ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1251ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 1252ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * Gets the root menu (if this is a submenu, find its root menu). 125320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 1254ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @return The root menu. 1255ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1256ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuBuilder getRootMenu() { 1257ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return this; 1258ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1259ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1260ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani /** 126120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the current menu info that is set on all items added to this menu (until this is called 126220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * again with different menu info, in which case that one will be added to all subsequent item 126320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * additions). 1264ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * 1265ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani * @param menuInfo The extra menu information to add. 1266ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani */ 1267ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public void setCurrentMenuInfo(ContextMenu.ContextMenuInfo menuInfo) { 1268ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mCurrentMenuInfo = menuInfo; 1269ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1270ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1271ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani void setOptionalIconsVisible(boolean visible) { 1272ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mOptionalIconsVisible = visible; 1273ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1274ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1275ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean getOptionalIconsVisible() { 1276ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mOptionalIconsVisible; 1277ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1278ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1279ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean expandItemActionView(MenuItemImpl item) { 128020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mPresenters.isEmpty()) { 128120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 128220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 1283ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1284ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean expanded = false; 1285ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1286ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani stopDispatchingItemsChanged(); 1287ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (WeakReference<MenuPresenter> ref : mPresenters) { 1288ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuPresenter presenter = ref.get(); 1289ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (presenter == null) { 1290ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.remove(ref); 1291ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else if ((expanded = presenter.expandItemActionView(this, item))) { 1292ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani break; 1293ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1294ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1295ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani startDispatchingItemsChanged(); 1296ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1297ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (expanded) { 1298ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mExpandedItem = item; 1299ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1300ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return expanded; 1301ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1302ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1303ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public boolean collapseItemActionView(MenuItemImpl item) { 130420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (mPresenters.isEmpty() || mExpandedItem != item) { 130520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns return false; 130620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 1307ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1308ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani boolean collapsed = false; 1309ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1310ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani stopDispatchingItemsChanged(); 1311ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani for (WeakReference<MenuPresenter> ref : mPresenters) { 1312ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani final MenuPresenter presenter = ref.get(); 1313ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (presenter == null) { 1314ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mPresenters.remove(ref); 1315ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } else if ((collapsed = presenter.collapseItemActionView(this, item))) { 1316ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani break; 1317ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1318ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1319ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani startDispatchingItemsChanged(); 1320ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1321ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani if (collapsed) { 1322ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani mExpandedItem = null; 1323ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1324ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return collapsed; 1325ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1326ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1327ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani public MenuItemImpl getExpandedItem() { 1328ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani return mExpandedItem; 1329ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani } 1330bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell} 1331ced50ab7536cd3d3573f03310fc899f10c414d37Anirudh Dewani 1332