FileDocCategorySizeDatePackage
MenuPopupHelper.javaAPI DocAndroid 5.1 API13437Thu Mar 12 22:22:10 GMT 2015com.android.internal.view.menu

MenuPopupHelper

public class MenuPopupHelper extends Object implements View.OnAttachStateChangeListener, PopupWindow.OnDismissListener, MenuPresenter, View.OnKeyListener, ViewTreeObserver.OnGlobalLayoutListener, AdapterView.OnItemClickListener
Presents a menu as a small, simple popup anchored to another view.
hide

Fields Summary
private static final String
TAG
static final int
ITEM_LAYOUT
private final android.content.Context
mContext
private final android.view.LayoutInflater
mInflater
private final MenuBuilder
mMenu
private final MenuAdapter
mAdapter
private final boolean
mOverflowOnly
private final int
mPopupMaxWidth
private final int
mPopupStyleAttr
private final int
mPopupStyleRes
private android.view.View
mAnchorView
private android.widget.ListPopupWindow
mPopup
private android.view.ViewTreeObserver
mTreeObserver
private Callback
mPresenterCallback
boolean
mForceShowIcon
private android.view.ViewGroup
mMeasureParent
private boolean
mHasContentWidth
Whether the cached content width value is valid.
private int
mContentWidth
Cached content width from {@link #measureContentWidth}.
private int
mDropDownGravity
Constructors Summary
public MenuPopupHelper(android.content.Context context, MenuBuilder menu)


         
        this(context, menu, null, false, com.android.internal.R.attr.popupMenuStyle, 0);
    
public MenuPopupHelper(android.content.Context context, MenuBuilder menu, android.view.View anchorView)

        this(context, menu, anchorView, false, com.android.internal.R.attr.popupMenuStyle, 0);
    
public MenuPopupHelper(android.content.Context context, MenuBuilder menu, android.view.View anchorView, boolean overflowOnly, int popupStyleAttr)

        this(context, menu, anchorView, overflowOnly, popupStyleAttr, 0);
    
public MenuPopupHelper(android.content.Context context, MenuBuilder menu, android.view.View anchorView, boolean overflowOnly, int popupStyleAttr, int popupStyleRes)

        mContext = context;
        mInflater = LayoutInflater.from(context);
        mMenu = menu;
        mAdapter = new MenuAdapter(mMenu);
        mOverflowOnly = overflowOnly;
        mPopupStyleAttr = popupStyleAttr;
        mPopupStyleRes = popupStyleRes;

        final Resources res = context.getResources();
        mPopupMaxWidth = Math.max(res.getDisplayMetrics().widthPixels / 2,
                res.getDimensionPixelSize(com.android.internal.R.dimen.config_prefDialogWidth));

        mAnchorView = anchorView;

        // Present the menu using our context, not the menu builder's context.
        menu.addMenuPresenter(this, context);
    
Methods Summary
public booleancollapseItemActionView(MenuBuilder menu, MenuItemImpl item)

        return false;
    
public voiddismiss()

        if (isShowing()) {
            mPopup.dismiss();
        }
    
public booleanexpandItemActionView(MenuBuilder menu, MenuItemImpl item)

        return false;
    
public booleanflagActionItems()

        return false;
    
public intgetId()

        return 0;
    
public MenuViewgetMenuView(android.view.ViewGroup root)

        throw new UnsupportedOperationException("MenuPopupHelpers manage their own views");
    
public android.widget.ListPopupWindowgetPopup()

        return mPopup;
    
public voidinitForMenu(android.content.Context context, MenuBuilder menu)

        // Don't need to do anything; we added as a presenter in the constructor.
    
public booleanisShowing()

        return mPopup != null && mPopup.isShowing();
    
private intmeasureContentWidth()

        // Menus don't tend to be long, so this is more sane than it looks.
        int maxWidth = 0;
        View itemView = null;
        int itemType = 0;

        final ListAdapter adapter = mAdapter;
        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        final int count = adapter.getCount();
        for (int i = 0; i < count; i++) {
            final int positionType = adapter.getItemViewType(i);
            if (positionType != itemType) {
                itemType = positionType;
                itemView = null;
            }

            if (mMeasureParent == null) {
                mMeasureParent = new FrameLayout(mContext);
            }

            itemView = adapter.getView(i, itemView, mMeasureParent);
            itemView.measure(widthMeasureSpec, heightMeasureSpec);

            final int itemWidth = itemView.getMeasuredWidth();
            if (itemWidth >= mPopupMaxWidth) {
                return mPopupMaxWidth;
            } else if (itemWidth > maxWidth) {
                maxWidth = itemWidth;
            }
        }

        return maxWidth;
    
public voidonCloseMenu(MenuBuilder menu, boolean allMenusAreClosing)

        // Only care about the (sub)menu we're presenting.
        if (menu != mMenu) return;

        dismiss();
        if (mPresenterCallback != null) {
            mPresenterCallback.onCloseMenu(menu, allMenusAreClosing);
        }
    
public voidonDismiss()

        mPopup = null;
        mMenu.close();
        if (mTreeObserver != null) {
            if (!mTreeObserver.isAlive()) mTreeObserver = mAnchorView.getViewTreeObserver();
            mTreeObserver.removeGlobalOnLayoutListener(this);
            mTreeObserver = null;
        }
        mAnchorView.removeOnAttachStateChangeListener(this);
    
public voidonGlobalLayout()

        if (isShowing()) {
            final View anchor = mAnchorView;
            if (anchor == null || !anchor.isShown()) {
                dismiss();
            } else if (isShowing()) {
                // Recompute window size and position
                mPopup.show();
            }
        }
    
public voidonItemClick(android.widget.AdapterView parent, android.view.View view, int position, long id)

        MenuAdapter adapter = mAdapter;
        adapter.mAdapterMenu.performItemAction(adapter.getItem(position), 0);
    
public booleanonKey(android.view.View v, int keyCode, android.view.KeyEvent event)

        if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_MENU) {
            dismiss();
            return true;
        }
        return false;
    
public voidonRestoreInstanceState(android.os.Parcelable state)

    
public android.os.ParcelableonSaveInstanceState()

        return null;
    
public booleanonSubMenuSelected(SubMenuBuilder subMenu)

        if (subMenu.hasVisibleItems()) {
            MenuPopupHelper subPopup = new MenuPopupHelper(mContext, subMenu, mAnchorView);
            subPopup.setCallback(mPresenterCallback);

            boolean preserveIconSpacing = false;
            final int count = subMenu.size();
            for (int i = 0; i < count; i++) {
                MenuItem childItem = subMenu.getItem(i);
                if (childItem.isVisible() && childItem.getIcon() != null) {
                    preserveIconSpacing = true;
                    break;
                }
            }
            subPopup.setForceShowIcon(preserveIconSpacing);

            if (subPopup.tryShow()) {
                if (mPresenterCallback != null) {
                    mPresenterCallback.onOpenSubMenu(subMenu);
                }
                return true;
            }
        }
        return false;
    
public voidonViewAttachedToWindow(android.view.View v)

    
public voidonViewDetachedFromWindow(android.view.View v)

        if (mTreeObserver != null) {
            if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver();
            mTreeObserver.removeGlobalOnLayoutListener(this);
        }
        v.removeOnAttachStateChangeListener(this);
    
public voidsetAnchorView(android.view.View anchor)

        mAnchorView = anchor;
    
public voidsetCallback(Callback cb)

        mPresenterCallback = cb;
    
public voidsetForceShowIcon(boolean forceShow)

        mForceShowIcon = forceShow;
    
public voidsetGravity(int gravity)

        mDropDownGravity = gravity;
    
public voidshow()

        if (!tryShow()) {
            throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
        }
    
public booleantryShow()

        mPopup = new ListPopupWindow(mContext, null, mPopupStyleAttr, mPopupStyleRes);
        mPopup.setOnDismissListener(this);
        mPopup.setOnItemClickListener(this);
        mPopup.setAdapter(mAdapter);
        mPopup.setModal(true);

        View anchor = mAnchorView;
        if (anchor != null) {
            final boolean addGlobalListener = mTreeObserver == null;
            mTreeObserver = anchor.getViewTreeObserver(); // Refresh to latest
            if (addGlobalListener) mTreeObserver.addOnGlobalLayoutListener(this);
            anchor.addOnAttachStateChangeListener(this);
            mPopup.setAnchorView(anchor);
            mPopup.setDropDownGravity(mDropDownGravity);
        } else {
            return false;
        }

        if (!mHasContentWidth) {
            mContentWidth = measureContentWidth();
            mHasContentWidth = true;
        }

        mPopup.setContentWidth(mContentWidth);
        mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
        mPopup.show();
        mPopup.getListView().setOnKeyListener(this);
        return true;
    
public voidupdateMenuView(boolean cleared)

        mHasContentWidth = false;

        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }