2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com
.actionbarsherlock
.internal
.view
.menu
;
19 import java
.util
.ArrayList
;
20 import android
.content
.Context
;
21 import android
.os
.Build
;
22 import android
.view
.LayoutInflater
;
23 import android
.view
.View
;
24 import android
.view
.ViewGroup
;
27 * Base class for MenuPresenters that have a consistent container view and item
28 * views. Behaves similarly to an AdapterView in that existing item views will
29 * be reused if possible when items change.
31 public abstract class BaseMenuPresenter
implements MenuPresenter
{
32 private static final boolean IS_HONEYCOMB
= Build
.VERSION
.SDK_INT
>= Build
.VERSION_CODES
.HONEYCOMB
;
34 protected Context mSystemContext
;
35 protected Context mContext
;
36 protected MenuBuilder mMenu
;
37 protected LayoutInflater mSystemInflater
;
38 protected LayoutInflater mInflater
;
39 private Callback mCallback
;
41 private int mMenuLayoutRes
;
42 private int mItemLayoutRes
;
44 protected MenuView mMenuView
;
49 * Construct a new BaseMenuPresenter.
51 * @param context Context for generating system-supplied views
52 * @param menuLayoutRes Layout resource ID for the menu container view
53 * @param itemLayoutRes Layout resource ID for a single item view
55 public BaseMenuPresenter(Context context
, int menuLayoutRes
, int itemLayoutRes
) {
56 mSystemContext
= context
;
57 mSystemInflater
= LayoutInflater
.from(context
);
58 mMenuLayoutRes
= menuLayoutRes
;
59 mItemLayoutRes
= itemLayoutRes
;
63 public void initForMenu(Context context
, MenuBuilder menu
) {
65 mInflater
= LayoutInflater
.from(mContext
);
70 public MenuView
getMenuView(ViewGroup root
) {
71 if (mMenuView
== null
) {
72 mMenuView
= (MenuView
) mSystemInflater
.inflate(mMenuLayoutRes
, root
, false
);
73 mMenuView
.initialize(mMenu
);
81 * Reuses item views when it can
83 public void updateMenuView(boolean cleared
) {
84 final ViewGroup parent
= (ViewGroup
) mMenuView
;
85 if (parent
== null
) return;
89 mMenu
.flagActionItems();
90 ArrayList
<MenuItemImpl
> visibleItems
= mMenu
.getVisibleItems();
91 final int itemCount
= visibleItems
.size();
92 for (int i
= 0; i
< itemCount
; i
++) {
93 MenuItemImpl item
= visibleItems
.get(i
);
94 if (shouldIncludeItem(childIndex
, item
)) {
95 final View convertView
= parent
.getChildAt(childIndex
);
96 final MenuItemImpl oldItem
= convertView
instanceof MenuView
.ItemView ?
97 ((MenuView
.ItemView
) convertView
).getItemData() : null
;
98 final View itemView
= getItemView(item
, convertView
, parent
);
99 if (item
!= oldItem
) {
100 // Don't let old states linger with new data.
101 itemView
.setPressed(false
);
102 if (IS_HONEYCOMB
) itemView
.jumpDrawablesToCurrentState();
104 if (itemView
!= convertView
) {
105 addItemView(itemView
, childIndex
);
112 // Remove leftover views.
113 while (childIndex
< parent
.getChildCount()) {
114 if (!filterLeftoverView(parent
, childIndex
)) {
121 * Add an item view at the given index.
123 * @param itemView View to add
124 * @param childIndex Index within the parent to insert at
126 protected void addItemView(View itemView
, int childIndex
) {
127 final ViewGroup currentParent
= (ViewGroup
) itemView
.getParent();
128 if (currentParent
!= null
) {
129 currentParent
.removeView(itemView
);
131 ((ViewGroup
) mMenuView
).addView(itemView
, childIndex
);
135 * Filter the child view at index and remove it if appropriate.
136 * @param parent Parent to filter from
137 * @param childIndex Index to filter
138 * @return true if the child view at index was removed
140 protected boolean filterLeftoverView(ViewGroup parent
, int childIndex
) {
141 parent
.removeViewAt(childIndex
);
145 public void setCallback(Callback cb
) {
150 * Create a new item view that can be re-bound to other item data later.
152 * @return The new item view
154 public MenuView
.ItemView
createItemView(ViewGroup parent
) {
155 return (MenuView
.ItemView
) mSystemInflater
.inflate(mItemLayoutRes
, parent
, false
);
159 * Prepare an item view for use. See AdapterView for the basic idea at work here.
160 * This may require creating a new item view, but well-behaved implementations will
161 * re-use the view passed as convertView if present. The returned view will be populated
162 * with data from the item parameter.
164 * @param item Item to present
165 * @param convertView Existing view to reuse
166 * @param parent Intended parent view - use for inflation.
167 * @return View that presents the requested menu item
169 public View
getItemView(MenuItemImpl item
, View convertView
, ViewGroup parent
) {
170 MenuView
.ItemView itemView
;
171 if (convertView
instanceof MenuView
.ItemView
) {
172 itemView
= (MenuView
.ItemView
) convertView
;
174 itemView
= createItemView(parent
);
176 bindItemView(item
, itemView
);
177 return (View
) itemView
;
181 * Bind item data to an existing item view.
183 * @param item Item to bind
184 * @param itemView View to populate with item data
186 public abstract void bindItemView(MenuItemImpl item
, MenuView
.ItemView itemView
);
189 * Filter item by child index and item data.
191 * @param childIndex Indended presentation index of this item
192 * @param item Item to present
193 * @return true if this item should be included in this menu presentation; false otherwise
195 public boolean shouldIncludeItem(int childIndex
, MenuItemImpl item
) {
199 public void onCloseMenu(MenuBuilder menu
, boolean allMenusAreClosing
) {
200 if (mCallback
!= null
) {
201 mCallback
.onCloseMenu(menu
, allMenusAreClosing
);
205 public boolean onSubMenuSelected(SubMenuBuilder menu
) {
206 if (mCallback
!= null
) {
207 return mCallback
.onOpenSubMenu(menu
);
212 public boolean flagActionItems() {
216 public boolean expandItemActionView(MenuBuilder menu
, MenuItemImpl item
) {
220 public boolean collapseItemActionView(MenuBuilder menu
, MenuItemImpl item
) {
228 public void setId(int id
) {