FileDocCategorySizeDatePackage
MenuItemImpl.javaAPI DocAndroid 1.5 API19981Wed May 06 22:41:56 BST 2009com.android.internal.view.menu

MenuItemImpl

public final class MenuItemImpl extends Object implements android.view.MenuItem
hide

Fields Summary
private final int
mId
private final int
mGroup
private final int
mCategoryOrder
private final int
mOrdering
private CharSequence
mTitle
private CharSequence
mTitleCondensed
private android.content.Intent
mIntent
private char
mShortcutNumericChar
private char
mShortcutAlphabeticChar
private android.graphics.drawable.Drawable
mIconDrawable
The icon's drawable which is only created as needed
private int
mIconResId
The icon's resource ID which is used to get the Drawable when it is needed (if the Drawable isn't already obtained--only one of the two is needed).
private WeakReference[]
mItemViews
The (cached) menu item views for this item
private MenuBuilder
mMenu
The menu to which this item belongs
private SubMenuBuilder
mSubMenu
If this item should launch a sub menu, this is the sub menu to launch
private Runnable
mItemCallback
private MenuItem.OnMenuItemClickListener
mClickListener
private int
mFlags
private static final int
CHECKABLE
private static final int
CHECKED
private static final int
EXCLUSIVE
private static final int
HIDDEN
private static final int
ENABLED
static final int
NO_ICON
Used for the icon resource ID if this item does not have an icon
private android.view.ContextMenu.ContextMenuInfo
mMenuInfo
Current use case is for context menu: Extra information linked to the View that added this item to the context menu.
private static String
sPrependShortcutLabel
private static String
sEnterShortcutLabel
private static String
sDeleteShortcutLabel
private static String
sSpaceShortcutLabel
Constructors Summary
MenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering, CharSequence title)
Instantiates this menu item. The constructor {@link #MenuItemData(MenuBuilder, int, int, int, CharSequence, int)} is preferred due to lazy loading of the icon Drawable.

param
menu
param
group Item ordering grouping control. The item will be added after all other items whose order is <= this number, and before any that are larger than it. This can also be used to define groups of items for batch state changes. Normally use 0.
param
id Unique item ID. Use 0 if you do not need a unique ID.
param
categoryOrder The ordering for this item.
param
title The text to display for the item.

    
    
                                                                                                                                                 
             
              

        if (sPrependShortcutLabel == null) {
            // This is instantiated from the UI thread, so no chance of sync issues 
            sPrependShortcutLabel = menu.getContext().getResources().getString(
                    com.android.internal.R.string.prepend_shortcut_label);
            sEnterShortcutLabel = menu.getContext().getResources().getString(
                    com.android.internal.R.string.menu_enter_shortcut_label);
            sDeleteShortcutLabel = menu.getContext().getResources().getString(
                    com.android.internal.R.string.menu_delete_shortcut_label);
            sSpaceShortcutLabel = menu.getContext().getResources().getString(
                    com.android.internal.R.string.menu_space_shortcut_label);
        }
        
        mItemViews = new WeakReference[MenuBuilder.NUM_TYPES];
        mMenu = menu;
        mId = id;
        mGroup = group;
        mCategoryOrder = categoryOrder;
        mOrdering = ordering;
        mTitle = title;
    
Methods Summary
voidclearItemViews()

        for (int i = mItemViews.length - 1; i >= 0; i--) {
            mItemViews[i] = null;
        }
    
private com.android.internal.view.menu.MenuView.ItemViewcreateItemView(int menuType, android.view.ViewGroup parent)
Create and initializes a menu item view that implements {@link MenuView.ItemView}.

param
menuType The type of menu to get a View for (must be one of {@link MenuBuilder#TYPE_ICON}, {@link MenuBuilder#TYPE_EXPANDED}, {@link MenuBuilder#TYPE_SUB}, {@link MenuBuilder#TYPE_CONTEXT}).
return
The inflated {@link MenuView.ItemView} that is ready for use

        // Create the MenuView
        MenuView.ItemView itemView = (MenuView.ItemView) getLayoutInflater(menuType)
                .inflate(MenuBuilder.ITEM_LAYOUT_RES_FOR_TYPE[menuType], parent, false);
        itemView.initialize(this, menuType);
        return itemView;
    
public chargetAlphabeticShortcut()

        return mShortcutAlphabeticChar;
    
java.lang.RunnablegetCallback()

        return mItemCallback;
    
public intgetGroupId()

        return mGroup;
    
public android.graphics.drawable.DrawablegetIcon()

        
        if (mIconDrawable != null) {
            return mIconDrawable;
        }

        if (mIconResId != NO_ICON) {
            return mMenu.getResources().getDrawable(mIconResId);
        }
        
        return null;
    
public android.content.IntentgetIntent()

        return mIntent;
    
public intgetItemId()

        return mId;
    
android.view.ViewgetItemView(int menuType, android.view.ViewGroup parent)

        if (!hasItemView(menuType)) {
            mItemViews[menuType] = new WeakReference<ItemView>(createItemView(menuType, parent));
        }
        
        return (View) mItemViews[menuType].get();
    
public android.view.LayoutInflatergetLayoutInflater(int menuType)
Returns a LayoutInflater that is themed for the given menu type.

param
menuType The type of menu.
return
A LayoutInflater.

        return mMenu.getMenuType(menuType).getInflater();
    
public android.view.ContextMenu.ContextMenuInfogetMenuInfo()

        return mMenuInfo;
    
public chargetNumericShortcut()

        return mShortcutNumericChar;
    
public intgetOrder()

        return mCategoryOrder;
    
public intgetOrdering()

        return mOrdering; 
    
chargetShortcut()

return
The active shortcut (based on QWERTY-mode of the menu).

        return (mMenu.isQwertyMode() ? mShortcutAlphabeticChar : mShortcutNumericChar);
    
java.lang.StringgetShortcutLabel()

return
The label to show for the shortcut. This includes the chording key (for example 'Menu+a'). Also, any non-human readable characters should be human readable (for example 'Menu+enter').


        char shortcut = getShortcut();
        if (shortcut == 0) {
            return "";
        }
        
        StringBuilder sb = new StringBuilder(sPrependShortcutLabel);
        switch (shortcut) {
        
            case '\n":
                sb.append(sEnterShortcutLabel);
                break;
            
            case '\b":
                sb.append(sDeleteShortcutLabel);
                break;
            
            case ' ":
                sb.append(sSpaceShortcutLabel);
                break;
            
            default:
                sb.append(shortcut);
                break;
        }
        
        return sb.toString();
    
public android.view.SubMenugetSubMenu()

        return mSubMenu;
    
public java.lang.CharSequencegetTitle()

        return mTitle;
    
public java.lang.CharSequencegetTitleCondensed()

        return mTitleCondensed != null ? mTitleCondensed : mTitle;
    
java.lang.CharSequencegetTitleForItemView(com.android.internal.view.menu.MenuView.ItemView itemView)
Gets the title for a particular {@link ItemView}

param
itemView The ItemView that is receiving the title
return
Either the title or condensed title based on what the ItemView prefers

        return ((itemView != null) && itemView.prefersCondensedTitle())
                ? getTitleCondensed()
                : getTitle();
    
private booleanhasItemView(int menuType)

        return mItemViews[menuType] != null && mItemViews[menuType].get() != null;
    
public booleanhasSubMenu()

        return mSubMenu != null;
    
private booleanhaveAnyOpenedIconCapableItemViews()

        for (int i = MenuBuilder.NUM_TYPES - 1; i >= 0; i--) {
            if (hasItemView(i) && mItemViews[i].get().showsIcon()) {
                return true;
            }
        }
        
        return false;
    
public booleaninvoke()
Invokes the item by calling various listeners or callbacks.

return
true if the invocation was handled, false otherwise

        if (mClickListener != null &&
            mClickListener.onMenuItemClick(this)) {
            return true;
        }

        MenuBuilder.Callback callback = mMenu.getCallback(); 
        if (callback != null &&
            callback.onMenuItemSelected(mMenu.getRootMenu(), this)) {
            return true;
        }

        if (mItemCallback != null) {
            mItemCallback.run();
            return true;
        }
        
        if (mIntent != null) {
            mMenu.getContext().startActivity(mIntent);
            return true;
        }
        
        return false;
    
public booleanisCheckable()

        return (mFlags & CHECKABLE) == CHECKABLE;
    
public booleanisChecked()

        return (mFlags & CHECKED) == CHECKED;
    
public booleanisEnabled()

        return (mFlags & ENABLED) != 0;
    
public booleanisExclusiveCheckable()

        return (mFlags & EXCLUSIVE) != 0;
    
public booleanisVisible()

        return (mFlags & HIDDEN) == 0;
    
private voidrefreshShortcutOnItemViews()
Refreshes the shortcut shown on the ItemViews. This method retrieves current shortcut state (mode and shown) from the menu that contains this item.

        refreshShortcutOnItemViews(mMenu.isShortcutsVisible(), mMenu.isQwertyMode());
    
voidrefreshShortcutOnItemViews(boolean menuShortcutShown, boolean isQwertyMode)
Refreshes the shortcut shown on the ItemViews. This is usually called by the {@link MenuBuilder} when it is refreshing the shortcuts on all item views, so it passes arguments rather than each item calling a method on the menu to get the same values.

param
menuShortcutShown The menu's shortcut shown mode. In addition, this method will ensure this item has a shortcut before it displays the shortcut.
param
isQwertyMode Whether the shortcut mode is qwerty mode

        final char shortcutKey = (isQwertyMode) ? mShortcutAlphabeticChar : mShortcutNumericChar;

        // Show shortcuts if the menu is supposed to show shortcuts AND this item has a shortcut
        final boolean showShortcut = menuShortcutShown && (shortcutKey != 0);
        
        for (int i = MenuBuilder.NUM_TYPES - 1; i >= 0; i--) {
            if (hasItemView(i)) {
                mItemViews[i].get().setShortcut(showShortcut, shortcutKey);
            }
        }
    
public android.view.MenuItemsetAlphabeticShortcut(char alphaChar)

        if (mShortcutAlphabeticChar == alphaChar) return this;
        
        mShortcutAlphabeticChar = Character.toLowerCase(alphaChar);
        
        refreshShortcutOnItemViews();
        
        return this;
    
public android.view.MenuItemsetCallback(java.lang.Runnable callback)

        mItemCallback = callback;
        return this;
    
public android.view.MenuItemsetCheckable(boolean checkable)

        final int oldFlags = mFlags;
        mFlags = (mFlags & ~CHECKABLE) | (checkable ? CHECKABLE : 0);
        if (oldFlags != mFlags) {
            for (int i = MenuBuilder.NUM_TYPES - 1; i >= 0; i--) {
                if (hasItemView(i)) {
                    mItemViews[i].get().setCheckable(checkable);
                }
            }
        }
        
        return this;
    
public android.view.MenuItemsetChecked(boolean checked)

        if ((mFlags & EXCLUSIVE) != 0) {
            // Call the method on the Menu since it knows about the others in this
            // exclusive checkable group
            mMenu.setExclusiveItemChecked(this);
        } else {
            setCheckedInt(checked);
        }
        
        return this;
    
voidsetCheckedInt(boolean checked)

        final int oldFlags = mFlags;
        mFlags = (mFlags & ~CHECKED) | (checked ? CHECKED : 0);
        if (oldFlags != mFlags) {
            for (int i = MenuBuilder.NUM_TYPES - 1; i >= 0; i--) {
                if (hasItemView(i)) {
                    mItemViews[i].get().setChecked(checked);
                }
            }
        }
    
public android.view.MenuItemsetEnabled(boolean enabled)

        if (enabled) {
            mFlags |= ENABLED;
        } else {
            mFlags &= ~ENABLED;
        }

        for (int i = MenuBuilder.NUM_TYPES - 1; i >= 0; i--) {
            // If the item view prefers a condensed title, only set this title if there
            // is no condensed title for this item
            if (hasItemView(i)) {
                mItemViews[i].get().setEnabled(enabled);
            }
        }
        
        return this;
    
public voidsetExclusiveCheckable(boolean exclusive)

        mFlags = (mFlags&~EXCLUSIVE) | (exclusive ? EXCLUSIVE : 0);
    
public android.view.MenuItemsetIcon(android.graphics.drawable.Drawable icon)

        mIconResId = NO_ICON;
        mIconDrawable = icon;
        setIconOnViews(icon);
        
        return this;
    
public android.view.MenuItemsetIcon(int iconResId)

        mIconDrawable = null;
        mIconResId = iconResId;

        // If we have a view, we need to push the Drawable to them
        if (haveAnyOpenedIconCapableItemViews()) {
            Drawable drawable = iconResId != NO_ICON ? mMenu.getResources().getDrawable(iconResId)
                    : null;
            setIconOnViews(drawable);
        }
        
        return this;
    
private voidsetIconOnViews(android.graphics.drawable.Drawable icon)

        for (int i = MenuBuilder.NUM_TYPES - 1; i >= 0; i--) {
            // Refresh those item views that are able to display an icon
            if (hasItemView(i) && mItemViews[i].get().showsIcon()) {
                mItemViews[i].get().setIcon(icon);
            }
        }
    
public android.view.MenuItemsetIntent(android.content.Intent intent)

        mIntent = intent;
        return this;
    
voidsetMenuInfo(android.view.ContextMenu.ContextMenuInfo menuInfo)

        mMenuInfo = menuInfo;
    
public android.view.MenuItemsetNumericShortcut(char numericChar)

        if (mShortcutNumericChar == numericChar) return this;
        
        mShortcutNumericChar = numericChar;
        
        refreshShortcutOnItemViews();
        
        return this;
    
public android.view.MenuItemsetOnMenuItemClickListener(MenuItem.OnMenuItemClickListener clickListener)

        mClickListener = clickListener;
        return this;
    
public android.view.MenuItemsetShortcut(char numericChar, char alphaChar)

        mShortcutNumericChar = numericChar;
        mShortcutAlphabeticChar = Character.toLowerCase(alphaChar);
        
        refreshShortcutOnItemViews();
        
        return this;
    
voidsetSubMenu(SubMenuBuilder subMenu)

        if ((mMenu != null) && (mMenu instanceof SubMenu)) {
            throw new UnsupportedOperationException(
            "Attempt to add a sub-menu to a sub-menu.");
        }
        
        mSubMenu = subMenu;
        
        subMenu.setHeaderTitle(getTitle());
    
public android.view.MenuItemsetTitle(java.lang.CharSequence title)

        mTitle = title;

        for (int i = MenuBuilder.NUM_TYPES - 1; i >= 0; i--) {
            // If the item view prefers a condensed title, only set this title if there
            // is no condensed title for this item
            if (!hasItemView(i)) {
                continue;
            }
            
            ItemView itemView = mItemViews[i].get(); 
            if (!itemView.prefersCondensedTitle() || mTitleCondensed == null) {
                itemView.setTitle(title);
            }
        }
        
        if (mSubMenu != null) {
            mSubMenu.setHeaderTitle(title);
        }
        
        return this;
    
public android.view.MenuItemsetTitle(int title)

        return setTitle(mMenu.getContext().getString(title));
    
public android.view.MenuItemsetTitleCondensed(java.lang.CharSequence title)

        mTitleCondensed = title;

        // Could use getTitle() in the loop below, but just cache what it would do here 
        if (title == null) {
            title = mTitle;
        }
        
        for (int i = MenuBuilder.NUM_TYPES - 1; i >= 0; i--) {
            // Refresh those item views that prefer a condensed title
            if (hasItemView(i) && (mItemViews[i].get().prefersCondensedTitle())) {
                mItemViews[i].get().setTitle(title);
            }
        }
        
        return this;
    
public android.view.MenuItemsetVisible(boolean shown)

        // Try to set the shown state to the given state. If the shown state was changed
        // (i.e. the previous state isn't the same as given state), notify the parent menu that
        // the shown state has changed for this item
        if (setVisibleInt(shown)) mMenu.onItemVisibleChanged(this);
        
        return this;
    
booleansetVisibleInt(boolean shown)
Changes the visibility of the item. This method DOES NOT notify the parent menu of a change in this item, so this should only be called from methods that will eventually trigger this change. If unsure, use {@link #setVisible(boolean)} instead.

param
shown Whether to show (true) or hide (false).
return
Whether the item's shown state was changed

        final int oldFlags = mFlags;
        mFlags = (mFlags & ~HIDDEN) | (shown ? 0 : HIDDEN);
        return oldFlags != mFlags;
    
public booleanshouldShowIcon(int menuType)

return
Whether the given menu type should show icons for menu items.

        return menuType == MenuBuilder.TYPE_ICON || mMenu.getOptionalIconsVisible();
    
booleanshouldShowShortcut()

return
Whether this menu item should be showing shortcuts (depends on whether the menu should show shortcuts and whether this item has a shortcut defined)

        // Show shortcuts if the menu is supposed to show shortcuts AND this item has a shortcut
        return mMenu.isShortcutsVisible() && (getShortcut() != 0);
    
public java.lang.StringtoString()

        return mTitle.toString();