BaseMenuPresenter.java revision 538e565c06e915b91e7e3a901f872ccdd9bccdd3
1696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell/*
2696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Copyright (C) 2011 The Android Open Source Project
3696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell *
4696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * you may not use this file except in compliance with the License.
6696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * You may obtain a copy of the License at
7696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell *
8696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell *
10696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Unless required by applicable law or agreed to in writing, software
11696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * See the License for the specific language governing permissions and
14696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * limitations under the License.
15696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */
16696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
17696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellpackage com.android.internal.view.menu;
18696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
19696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.content.Context;
20696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.LayoutInflater;
21696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.View;
22696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.ViewGroup;
23696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
24696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport java.util.ArrayList;
25696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
26696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell/**
27696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Base class for MenuPresenters that have a consistent container view and item
28696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * views. Behaves similarly to an AdapterView in that existing item views will
29696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * be reused if possible when items change.
30696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */
31696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellpublic abstract class BaseMenuPresenter implements MenuPresenter {
32538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell    protected Context mSystemContext;
33696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    protected Context mContext;
34696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    protected MenuBuilder mMenu;
35538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell    protected LayoutInflater mSystemInflater;
36696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    protected LayoutInflater mInflater;
37696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private Callback mCallback;
38696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
39696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private int mMenuLayoutRes;
40696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private int mItemLayoutRes;
41696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
42696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    protected MenuView mMenuView;
43696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
4411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    private int mId;
4511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
46696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
47696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Construct a new BaseMenuPresenter.
48696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
49538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell     * @param context Context for generating system-supplied views
50696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param menuLayoutRes Layout resource ID for the menu container view
51696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param itemLayoutRes Layout resource ID for a single item view
52696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
53538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell    public BaseMenuPresenter(Context context, int menuLayoutRes, int itemLayoutRes) {
54538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell        mSystemContext = context;
55538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell        mSystemInflater = LayoutInflater.from(context);
56696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mMenuLayoutRes = menuLayoutRes;
57696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mItemLayoutRes = itemLayoutRes;
58696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
59696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
60696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
61696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void initForMenu(Context context, MenuBuilder menu) {
62696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mContext = context;
63696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mInflater = LayoutInflater.from(mContext);
64696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mMenu = menu;
65696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
66696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
67696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
68696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public MenuView getMenuView(ViewGroup root) {
69696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mMenuView == null) {
70538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell            mMenuView = (MenuView) mSystemInflater.inflate(mMenuLayoutRes, root, false);
71696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mMenuView.initialize(mMenu);
72696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            updateMenuView(true);
73696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
74696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
75696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return mMenuView;
76696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
77696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
78696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
79696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Reuses item views when it can
80696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
81696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void updateMenuView(boolean cleared) {
82696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final ViewGroup parent = (ViewGroup) mMenuView;
83f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell        if (parent == null) return;
84f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell
85696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        int childIndex = 0;
86f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell        if (mMenu != null) {
87f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell            mMenu.flagActionItems();
88f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell            ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
89f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell            final int itemCount = visibleItems.size();
90f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell            for (int i = 0; i < itemCount; i++) {
91f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell                MenuItemImpl item = visibleItems.get(i);
92f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell                if (shouldIncludeItem(childIndex, item)) {
93f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell                    final View convertView = parent.getChildAt(childIndex);
94f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell                    final View itemView = getItemView(item, convertView, parent);
95f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell                    if (itemView != convertView) {
96f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell                        addItemView(itemView, childIndex);
97f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell                    }
98f35d049b9953fbd1cd24887bac57b5e148c97846Adam Powell                    childIndex++;
99696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                }
100696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
101696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
102696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
103696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        // Remove leftover views.
104696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        while (childIndex < parent.getChildCount()) {
105696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (!filterLeftoverView(parent, childIndex)) {
106696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                childIndex++;
107696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
108696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
109696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
110696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
111696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
112696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Add an item view at the given index.
113696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
114696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param itemView View to add
115696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param childIndex Index within the parent to insert at
116696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
117696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    protected void addItemView(View itemView, int childIndex) {
11845c515b0e962ee8ffc901872bcc9f25599ea0e78Adam Powell        final ViewGroup currentParent = (ViewGroup) itemView.getParent();
11945c515b0e962ee8ffc901872bcc9f25599ea0e78Adam Powell        if (currentParent != null) {
12045c515b0e962ee8ffc901872bcc9f25599ea0e78Adam Powell            currentParent.removeView(itemView);
12145c515b0e962ee8ffc901872bcc9f25599ea0e78Adam Powell        }
122696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        ((ViewGroup) mMenuView).addView(itemView, childIndex);
123696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
124696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
125696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
126696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Filter the child view at index and remove it if appropriate.
127696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param parent Parent to filter from
128696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param childIndex Index to filter
129696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return true if the child view at index was removed
130696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
131696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    protected boolean filterLeftoverView(ViewGroup parent, int childIndex) {
132696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        parent.removeViewAt(childIndex);
133696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return true;
134696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
135696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
136696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void setCallback(Callback cb) {
137696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mCallback = cb;
138696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
139696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
140696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
141696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Create a new item view that can be re-bound to other item data later.
142696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
143696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return The new item view
144696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
145696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public MenuView.ItemView createItemView(ViewGroup parent) {
146538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell        return (MenuView.ItemView) mSystemInflater.inflate(mItemLayoutRes, parent, false);
147696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
148696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
149696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
150696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Prepare an item view for use. See AdapterView for the basic idea at work here.
151696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * This may require creating a new item view, but well-behaved implementations will
152696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * re-use the view passed as convertView if present. The returned view will be populated
153696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * with data from the item parameter.
154696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
155696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param item Item to present
156696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param convertView Existing view to reuse
157696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param parent Intended parent view - use for inflation.
158696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return View that presents the requested menu item
159696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
160696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) {
161696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        MenuView.ItemView itemView;
162696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (convertView instanceof MenuView.ItemView) {
163696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            itemView = (MenuView.ItemView) convertView;
164696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        } else {
165696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            itemView = createItemView(parent);
166696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
167696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        bindItemView(item, itemView);
168696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return (View) itemView;
169696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
170696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
171696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
172696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Bind item data to an existing item view.
173696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
174696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param item Item to bind
175696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param itemView View to populate with item data
176696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
177696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public abstract void bindItemView(MenuItemImpl item, MenuView.ItemView itemView);
178696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
179696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
180696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Filter item by child index and item data.
181696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
182696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param childIndex Indended presentation index of this item
183696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @param item Item to present
184696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return true if this item should be included in this menu presentation; false otherwise
185696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
186696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
187696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return true;
188696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
189696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
190696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
191696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mCallback != null) {
192696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mCallback.onCloseMenu(menu, allMenusAreClosing);
193696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
194696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
195696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
196696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean onSubMenuSelected(SubMenuBuilder menu) {
197696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mCallback != null) {
198696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            return mCallback.onOpenSubMenu(menu);
199696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
200696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return false;
201696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
202696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
203696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean flagActionItems() {
204696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return false;
205696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
2068d02deabac62c4a68a335a7b3141795466362b89Adam Powell
2078d02deabac62c4a68a335a7b3141795466362b89Adam Powell    public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
2088d02deabac62c4a68a335a7b3141795466362b89Adam Powell        return false;
2098d02deabac62c4a68a335a7b3141795466362b89Adam Powell    }
2108d02deabac62c4a68a335a7b3141795466362b89Adam Powell
2118d02deabac62c4a68a335a7b3141795466362b89Adam Powell    public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
2128d02deabac62c4a68a335a7b3141795466362b89Adam Powell        return false;
2138d02deabac62c4a68a335a7b3141795466362b89Adam Powell    }
21411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
21511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    public int getId() {
21611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        return mId;
21711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    }
21811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
21911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    public void setId(int id) {
22011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        mId = id;
22111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    }
222696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell}
223