1 /* 2 * Copyright (C) 2007 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 17 package android.view.menu; 18 19 import android.util.ListScenario; 20 import com.android.internal.view.menu.MenuBuilder; 21 import com.android.internal.view.menu.MenuBuilder.MenuAdapter; 22 23 import android.app.Activity; 24 import android.os.Bundle; 25 import android.util.SparseArray; 26 import android.view.Menu; 27 import android.view.MenuItem; 28 import android.view.View; 29 30 /** 31 * Utility base class for creating various Menu scenarios. Configurable by the 32 * number of menu items. Used @link {@link ListScenario} as a reference. 33 */ 34 public class MenuScenario extends Activity implements MenuItem.OnMenuItemClickListener { 35 private Params mParams = new Params(); 36 private Menu mMenu; 37 private MenuItem[] mItems; 38 private boolean[] mWasItemClicked; 39 private MenuAdapter[] mMenuAdapters = new MenuAdapter[MenuBuilder.NUM_TYPES]; 40 41 @Override 42 protected void onCreate(Bundle icicle) { 43 super.onCreate(icicle); 44 45 dispatchInitParams(); 46 } 47 48 private void dispatchInitParams() { 49 onInitParams(mParams); 50 onParamsChanged(); 51 } 52 53 public void setParams(Params params) { 54 mParams = params; 55 onParamsChanged(); 56 } 57 58 public void onParamsChanged() { 59 mItems = new MenuItem[mParams.numItems]; 60 mWasItemClicked = new boolean[mParams.numItems]; 61 } 62 63 @Override 64 public boolean onCreateOptionsMenu(Menu menu) { 65 // Safe to hold on to 66 mMenu = menu; 67 68 if (!mParams.shouldShowMenu) return false; 69 70 MenuItem item; 71 for (int i = 0; i < mParams.numItems; i++) { 72 if ((item = onAddMenuItem(menu, i)) == null) { 73 // Add a default item for this position if the subclasses 74 // haven't 75 CharSequence givenTitle = mParams.itemTitles.get(i); 76 item = menu.add(0, 0, 0, (givenTitle != null) ? givenTitle : ("Item " + i)); 77 } 78 79 if (item != null) { 80 mItems[i] = item; 81 82 if (mParams.listenForClicks) { 83 item.setOnMenuItemClickListener(this); 84 } 85 } 86 87 } 88 89 return true; 90 } 91 92 @Override 93 public boolean onPrepareOptionsMenu(Menu menu) { 94 // Safe to hold on to 95 mMenu = menu; 96 97 return mParams.shouldShowMenu; 98 } 99 100 /** 101 * Override this to add an item to the menu. 102 * 103 * @param itemPosition The position of the item to add (only for your 104 * reference). 105 * @return The item that was added to the menu, or null if nothing was 106 * added. 107 */ 108 protected MenuItem onAddMenuItem(Menu menu, int itemPosition) { 109 return null; 110 } 111 112 /** 113 * Override this to set the parameters for the scenario. Call through to super first. 114 * 115 * @param params 116 */ 117 protected void onInitParams(Params params) { 118 } 119 120 public Menu getMenu() { 121 return mMenu; 122 } 123 124 public boolean onMenuItemClick(MenuItem item) { 125 final int position = findItemPosition(item); 126 if (position < 0) return false; 127 128 mWasItemClicked[position] = true; 129 130 return true; 131 } 132 133 public boolean wasItemClicked(int position) { 134 return mWasItemClicked[position]; 135 } 136 137 /** 138 * Finds the position for a given Item. 139 * 140 * @param item The item to find. 141 * @return The position, or -1 if not found. 142 */ 143 public int findItemPosition(MenuItem item) { 144 // Could create reverse mapping, but optimizations aren't important (yet :P) 145 for (int i = 0; i < mParams.numItems; i++) { 146 if (mItems[i] == item) return i; 147 } 148 149 return -1; 150 } 151 152 /** 153 * @see MenuBuilder#getMenuAdapter(int) 154 */ 155 public MenuAdapter getMenuAdapter(int menuType) { 156 if (mMenuAdapters[menuType] == null) { 157 mMenuAdapters[menuType] = ((MenuBuilder) mMenu).getMenuAdapter(menuType); 158 } 159 160 return mMenuAdapters[menuType]; 161 } 162 163 /** 164 * Gets a menu view. Call this after you're sure it has been shown, 165 * otherwise it may not have the proper layout_* attributes set. 166 * 167 * @param menuType The type of menu. 168 * @return The MenuView for that type. 169 */ 170 public View getMenuView(int menuType) { 171 return ((MenuBuilder) mMenu).getMenuView(menuType, null); 172 } 173 174 /** 175 * Gets the menu item view for a given position. 176 * 177 * @param menuType The type of menu. 178 * @param position The position of the item. 179 * @return The menu item view for the given item in the given menu type. 180 */ 181 public View getItemView(int menuType, int position) { 182 return getMenuAdapter(menuType).getView(position, null, null); 183 } 184 185 public static class Params { 186 // Using as data structure, so no m prefix 187 private boolean shouldShowMenu = true; 188 private int numItems = 10; 189 private boolean listenForClicks = true; 190 private SparseArray<CharSequence> itemTitles = new SparseArray<CharSequence>(); 191 192 public Params setShouldShowMenu(boolean shouldShowMenu) { 193 this.shouldShowMenu = shouldShowMenu; 194 return this; 195 } 196 197 public Params setNumItems(int numItems) { 198 this.numItems = numItems; 199 return this; 200 } 201 202 public Params setListenForClicks(boolean listenForClicks) { 203 this.listenForClicks = listenForClicks; 204 return this; 205 } 206 207 public Params setItemTitle(int itemPos, CharSequence title) { 208 itemTitles.put(itemPos, title); 209 return this; 210 } 211 } 212 } 213