1/* 2 * Copyright (C) 2012 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.support.v7.internal.view.menu; 18 19import android.annotation.TargetApi; 20import android.content.Context; 21import android.content.Intent; 22import android.graphics.drawable.Drawable; 23import android.os.Build; 24import android.support.v4.internal.view.SupportMenuItem; 25import android.support.v4.view.ActionProvider; 26import android.support.v4.view.MenuItemCompat; 27import android.support.v7.view.CollapsibleActionView; 28import android.util.Log; 29import android.view.ContextMenu; 30import android.view.MenuItem; 31import android.view.SubMenu; 32import android.view.View; 33import android.widget.FrameLayout; 34 35import java.lang.reflect.Method; 36 37/** 38 * Wraps a support {@link SupportMenuItem} as a framework {@link android.view.MenuItem} 39 * @hide 40 */ 41@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 42public class MenuItemWrapperICS extends BaseMenuWrapper<SupportMenuItem> implements MenuItem { 43 static final String LOG_TAG = "MenuItemWrapper"; 44 45 // Reflection Method to call setExclusiveCheckable 46 private Method mSetExclusiveCheckableMethod; 47 48 MenuItemWrapperICS(Context context, SupportMenuItem object) { 49 super(context, object); 50 } 51 52 @Override 53 public int getItemId() { 54 return mWrappedObject.getItemId(); 55 } 56 57 @Override 58 public int getGroupId() { 59 return mWrappedObject.getGroupId(); 60 } 61 62 @Override 63 public int getOrder() { 64 return mWrappedObject.getOrder(); 65 } 66 67 @Override 68 public MenuItem setTitle(CharSequence title) { 69 mWrappedObject.setTitle(title); 70 return this; 71 } 72 73 @Override 74 public MenuItem setTitle(int title) { 75 mWrappedObject.setTitle(title); 76 return this; 77 } 78 79 @Override 80 public CharSequence getTitle() { 81 return mWrappedObject.getTitle(); 82 } 83 84 @Override 85 public MenuItem setTitleCondensed(CharSequence title) { 86 mWrappedObject.setTitleCondensed(title); 87 return this; 88 } 89 90 @Override 91 public CharSequence getTitleCondensed() { 92 return mWrappedObject.getTitleCondensed(); 93 } 94 95 @Override 96 public MenuItem setIcon(Drawable icon) { 97 mWrappedObject.setIcon(icon); 98 return this; 99 } 100 101 @Override 102 public MenuItem setIcon(int iconRes) { 103 mWrappedObject.setIcon(iconRes); 104 return this; 105 } 106 107 @Override 108 public Drawable getIcon() { 109 return mWrappedObject.getIcon(); 110 } 111 112 @Override 113 public MenuItem setIntent(Intent intent) { 114 mWrappedObject.setIntent(intent); 115 return this; 116 } 117 118 @Override 119 public Intent getIntent() { 120 return mWrappedObject.getIntent(); 121 } 122 123 @Override 124 public MenuItem setShortcut(char numericChar, char alphaChar) { 125 mWrappedObject.setShortcut(numericChar, alphaChar); 126 return this; 127 } 128 129 @Override 130 public MenuItem setNumericShortcut(char numericChar) { 131 mWrappedObject.setNumericShortcut(numericChar); 132 return this; 133 } 134 135 @Override 136 public char getNumericShortcut() { 137 return mWrappedObject.getNumericShortcut(); 138 } 139 140 @Override 141 public MenuItem setAlphabeticShortcut(char alphaChar) { 142 mWrappedObject.setAlphabeticShortcut(alphaChar); 143 return this; 144 } 145 146 @Override 147 public char getAlphabeticShortcut() { 148 return mWrappedObject.getAlphabeticShortcut(); 149 } 150 151 @Override 152 public MenuItem setCheckable(boolean checkable) { 153 mWrappedObject.setCheckable(checkable); 154 return this; 155 } 156 157 @Override 158 public boolean isCheckable() { 159 return mWrappedObject.isCheckable(); 160 } 161 162 @Override 163 public MenuItem setChecked(boolean checked) { 164 mWrappedObject.setChecked(checked); 165 return this; 166 } 167 168 @Override 169 public boolean isChecked() { 170 return mWrappedObject.isChecked(); 171 } 172 173 @Override 174 public MenuItem setVisible(boolean visible) { 175 return mWrappedObject.setVisible(visible); 176 } 177 178 @Override 179 public boolean isVisible() { 180 return mWrappedObject.isVisible(); 181 } 182 183 @Override 184 public MenuItem setEnabled(boolean enabled) { 185 mWrappedObject.setEnabled(enabled); 186 return this; 187 } 188 189 @Override 190 public boolean isEnabled() { 191 return mWrappedObject.isEnabled(); 192 } 193 194 @Override 195 public boolean hasSubMenu() { 196 return mWrappedObject.hasSubMenu(); 197 } 198 199 @Override 200 public SubMenu getSubMenu() { 201 return getSubMenuWrapper(mWrappedObject.getSubMenu()); 202 } 203 204 @Override 205 public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) { 206 mWrappedObject.setOnMenuItemClickListener(menuItemClickListener != null ? 207 new OnMenuItemClickListenerWrapper(menuItemClickListener) : null); 208 return this; 209 } 210 211 @Override 212 public ContextMenu.ContextMenuInfo getMenuInfo() { 213 return mWrappedObject.getMenuInfo(); 214 } 215 216 @Override 217 public void setShowAsAction(int actionEnum) { 218 mWrappedObject.setShowAsAction(actionEnum); 219 } 220 221 @Override 222 public MenuItem setShowAsActionFlags(int actionEnum) { 223 mWrappedObject.setShowAsActionFlags(actionEnum); 224 return this; 225 } 226 227 @Override 228 public MenuItem setActionView(View view) { 229 if (view instanceof android.view.CollapsibleActionView) { 230 view = new CollapsibleActionViewWrapper(view); 231 } 232 mWrappedObject.setActionView(view); 233 return this; 234 } 235 236 @Override 237 public MenuItem setActionView(int resId) { 238 // Make framework menu item inflate the view 239 mWrappedObject.setActionView(resId); 240 241 View actionView = mWrappedObject.getActionView(); 242 if (actionView instanceof android.view.CollapsibleActionView) { 243 // If the inflated Action View is support-collapsible, wrap it 244 mWrappedObject.setActionView(new CollapsibleActionViewWrapper(actionView)); 245 } 246 return this; 247 } 248 249 @Override 250 public View getActionView() { 251 View actionView = mWrappedObject.getActionView(); 252 if (actionView instanceof CollapsibleActionViewWrapper) { 253 return ((CollapsibleActionViewWrapper) actionView).getWrappedView(); 254 } 255 return actionView; 256 } 257 258 @Override 259 public MenuItem setActionProvider(android.view.ActionProvider provider) { 260 mWrappedObject.setSupportActionProvider( 261 provider != null ? createActionProviderWrapper(provider) : null); 262 return this; 263 } 264 265 @Override 266 public android.view.ActionProvider getActionProvider() { 267 ActionProvider provider = mWrappedObject.getSupportActionProvider(); 268 if (provider instanceof ActionProviderWrapper) { 269 return ((ActionProviderWrapper) provider).mInner; 270 } 271 return null; 272 } 273 274 @Override 275 public boolean expandActionView() { 276 return mWrappedObject.expandActionView(); 277 } 278 279 @Override 280 public boolean collapseActionView() { 281 return mWrappedObject.collapseActionView(); 282 } 283 284 @Override 285 public boolean isActionViewExpanded() { 286 return mWrappedObject.isActionViewExpanded(); 287 } 288 289 @Override 290 public MenuItem setOnActionExpandListener(MenuItem.OnActionExpandListener listener) { 291 mWrappedObject.setSupportOnActionExpandListener(listener != null ? 292 new OnActionExpandListenerWrapper(listener) : null); 293 return this; 294 } 295 296 public void setExclusiveCheckable(boolean checkable) { 297 try { 298 if (mSetExclusiveCheckableMethod == null) { 299 mSetExclusiveCheckableMethod = mWrappedObject.getClass() 300 .getDeclaredMethod("setExclusiveCheckable", Boolean.TYPE); 301 } 302 mSetExclusiveCheckableMethod.invoke(mWrappedObject, checkable); 303 } catch (Exception e) { 304 Log.w(LOG_TAG, "Error while calling setExclusiveCheckable", e); 305 } 306 } 307 308 ActionProviderWrapper createActionProviderWrapper(android.view.ActionProvider provider) { 309 return new ActionProviderWrapper(mContext, provider); 310 } 311 312 private class OnMenuItemClickListenerWrapper extends BaseWrapper<OnMenuItemClickListener> 313 implements android.view.MenuItem.OnMenuItemClickListener { 314 315 OnMenuItemClickListenerWrapper(OnMenuItemClickListener object) { 316 super(object); 317 } 318 319 @Override 320 public boolean onMenuItemClick(android.view.MenuItem item) { 321 return mWrappedObject.onMenuItemClick(getMenuItemWrapper(item)); 322 } 323 } 324 325 private class OnActionExpandListenerWrapper extends BaseWrapper<MenuItem.OnActionExpandListener> 326 implements MenuItemCompat.OnActionExpandListener { 327 328 OnActionExpandListenerWrapper(MenuItem.OnActionExpandListener object) { 329 super(object); 330 } 331 332 @Override 333 public boolean onMenuItemActionExpand(android.view.MenuItem item) { 334 return mWrappedObject.onMenuItemActionExpand(getMenuItemWrapper(item)); 335 } 336 337 @Override 338 public boolean onMenuItemActionCollapse(android.view.MenuItem item) { 339 return mWrappedObject.onMenuItemActionCollapse(getMenuItemWrapper(item)); 340 } 341 } 342 343 class ActionProviderWrapper extends android.support.v4.view.ActionProvider { 344 final android.view.ActionProvider mInner; 345 346 public ActionProviderWrapper(Context context, android.view.ActionProvider inner) { 347 super(context); 348 mInner = inner; 349 } 350 351 @Override 352 public View onCreateActionView() { 353 return mInner.onCreateActionView(); 354 } 355 356 @Override 357 public boolean onPerformDefaultAction() { 358 return mInner.onPerformDefaultAction(); 359 } 360 361 @Override 362 public boolean hasSubMenu() { 363 return mInner.hasSubMenu(); 364 } 365 366 @Override 367 public void onPrepareSubMenu(android.view.SubMenu subMenu) { 368 mInner.onPrepareSubMenu(getSubMenuWrapper(subMenu)); 369 } 370 } 371 372 /** 373 * Wrap a support {@link android.support.v7.view.CollapsibleActionView} into a framework 374 * {@link android.view.CollapsibleActionView}. 375 */ 376 static class CollapsibleActionViewWrapper extends FrameLayout 377 implements CollapsibleActionView { 378 379 final android.view.CollapsibleActionView mWrappedView; 380 381 CollapsibleActionViewWrapper(View actionView) { 382 super(actionView.getContext()); 383 mWrappedView = (android.view.CollapsibleActionView) actionView; 384 addView(actionView); 385 } 386 387 @Override 388 public void onActionViewExpanded() { 389 mWrappedView.onActionViewExpanded(); 390 } 391 392 @Override 393 public void onActionViewCollapsed() { 394 mWrappedView.onActionViewCollapsed(); 395 } 396 397 View getWrappedView() { 398 return (View) mWrappedView; 399 } 400 } 401} 402