PopupMenu.java revision 4be0d52125b88dc992a4c500edbe95bf55484e0b
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.widget;
18
19import com.android.internal.view.menu.MenuBuilder;
20import com.android.internal.view.menu.MenuPopupHelper;
21import com.android.internal.view.menu.SubMenuBuilder;
22
23import android.content.Context;
24import android.view.Menu;
25import android.view.MenuInflater;
26import android.view.MenuItem;
27import android.view.View;
28
29/**
30 * A PopupMenu displays a {@link Menu} in a modal popup window anchored to a {@link View}.
31 * The popup will appear below the anchor view if there is room, or above it if there is not.
32 * If the IME is visible the popup will not overlap it until it is touched. Touching outside
33 * of the popup will dismiss it.
34 */
35public class PopupMenu implements MenuBuilder.Callback {
36    private Context mContext;
37    private MenuBuilder mMenu;
38    private View mAnchor;
39    private MenuPopupHelper mPopup;
40    private OnMenuItemClickListener mMenuItemClickListener;
41
42    /**
43     * Construct a new PopupMenu.
44     *
45     * @param context Context for the PopupMenu.
46     * @param anchor Anchor view for this popup. The popup will appear below the anchor if there
47     *               is room, or above it if there is not.
48     */
49    public PopupMenu(Context context, View anchor) {
50        // TODO Theme?
51        mContext = context;
52        mMenu = new MenuBuilder(context);
53        mMenu.setCallback(this);
54        mAnchor = anchor;
55        mPopup = new MenuPopupHelper(context, mMenu, anchor);
56    }
57
58    /**
59     * @return the {@link Menu} associated with this popup. Populate the returned Menu with
60     * items before calling {@link #show()}.
61     *
62     * @see #show()
63     * @see #getMenuInflater()
64     */
65    public Menu getMenu() {
66        return mMenu;
67    }
68
69    /**
70     * @return a {@link MenuInflater} that can be used to inflate menu items from XML into the
71     * menu returned by {@link #getMenu()}.
72     *
73     * @see #getMenu()
74     */
75    public MenuInflater getMenuInflater() {
76        return new MenuInflater(mContext);
77    }
78
79    /**
80     * Show the menu popup anchored to the view specified during construction.
81     * @see #dismiss()
82     */
83    public void show() {
84        mPopup.show();
85    }
86
87    /**
88     * Dismiss the menu popup.
89     * @see #show()
90     */
91    public void dismiss() {
92        mPopup.dismiss();
93    }
94
95    public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
96        mMenuItemClickListener = listener;
97    }
98
99    /**
100     * @hide
101     */
102    public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
103        if (mMenuItemClickListener != null) {
104            return mMenuItemClickListener.onMenuItemClick(item);
105        }
106        return false;
107    }
108
109    /**
110     * @hide
111     */
112    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
113    }
114
115    /**
116     * @hide
117     */
118    public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
119        if (!subMenu.hasVisibleItems()) {
120            return true;
121        }
122
123        // Current menu will be dismissed by the normal helper, submenu will be shown in its place.
124        new MenuPopupHelper(mContext, subMenu, mAnchor).show();
125        return true;
126    }
127
128    /**
129     * @hide
130     */
131    public void onCloseSubMenu(SubMenuBuilder menu) {
132    }
133
134    /**
135     * @hide
136     */
137    public void onMenuModeChange(MenuBuilder menu) {
138    }
139
140    /**
141     * Interface responsible for receiving menu item click events if the items themselves
142     * do not have individual item click listeners.
143     */
144    public interface OnMenuItemClickListener {
145        /**
146         * This method will be invoked when a menu item is clicked if the item itself did
147         * not already handle the event.
148         *
149         * @param item {@link MenuItem} that was clicked
150         * @return <code>true</code> if the event was handled, <code>false</code> otherwise.
151         */
152        public boolean onMenuItemClick(MenuItem item);
153    }
154}
155