MenuPopupHelper.java revision 4267534d1c42af847ed0cefd1c88c99f66b36571
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 com.android.internal.view.menu;
18
19import com.android.internal.view.menu.MenuBuilder.MenuAdapter;
20
21import android.content.Context;
22import android.util.DisplayMetrics;
23import android.view.View;
24import android.view.View.MeasureSpec;
25import android.widget.AdapterView;
26import android.widget.ListPopupWindow;
27
28/**
29 * @hide
30 */
31public class MenuPopupHelper implements AdapterView.OnItemClickListener {
32    private static final String TAG = "MenuPopupHelper";
33
34    private Context mContext;
35    private ListPopupWindow mPopup;
36    private SubMenuBuilder mSubMenu;
37    private int mPopupMaxWidth;
38
39    public MenuPopupHelper(Context context, SubMenuBuilder subMenu) {
40        mContext = context;
41        mSubMenu = subMenu;
42
43        final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
44        mPopupMaxWidth = metrics.widthPixels / 2;
45    }
46
47    public void show() {
48        // TODO Use a style from the theme here
49        mPopup = new ListPopupWindow(mContext, null, 0,
50                com.android.internal.R.style.Widget_Spinner);
51        mPopup.setOnItemClickListener(this);
52
53        final MenuAdapter adapter = mSubMenu.getMenuAdapter(MenuBuilder.TYPE_POPUP);
54        mPopup.setAdapter(adapter);
55        mPopup.setModal(true);
56
57        final MenuItemImpl itemImpl = (MenuItemImpl) mSubMenu.getItem();
58        final View anchorView = itemImpl.getItemView(MenuBuilder.TYPE_ACTION_BUTTON, null);
59        mPopup.setAnchorView(anchorView);
60
61        mPopup.setContentWidth(Math.min(measureContentWidth(adapter), mPopupMaxWidth));
62        mPopup.show();
63    }
64
65    public void dismiss() {
66        mPopup.dismiss();
67        mPopup = null;
68    }
69
70    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
71        mSubMenu.performItemAction(mSubMenu.getItem(position), 0);
72        mPopup.dismiss();
73    }
74
75    private int measureContentWidth(MenuAdapter adapter) {
76        // Menus don't tend to be long, so this is more sane than it looks.
77        int width = 0;
78        View itemView = null;
79        final int widthMeasureSpec =
80            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
81        final int heightMeasureSpec =
82            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
83        final int count = adapter.getCount();
84        for (int i = 0; i < count; i++) {
85            itemView = adapter.getView(i, itemView, null);
86            itemView.measure(widthMeasureSpec, heightMeasureSpec);
87            width = Math.max(width, itemView.getMeasuredWidth());
88        }
89        return width;
90    }
91}
92