After updating my project to use the appcompat library to version 21.0.0 I have a problem with a context menu created with a gridview multichoice modal event. The same code works nice with appcompat v20.
This is the relevant part of the main activity:
public class MainActivity extends android.support.v7.app.ActionBarActivity
implements AbsListView.MultiChoiceModeListener {
...
mGridView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
mGridView.setMultiChoiceModeListener(this);
@Override
public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
mode.setTitle("Started");
mode.getMenuInflater().inflate(R.menu.context_menu, menu);
return true;
}
}
and this is the context_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_item_share"
android:title="Share..."
app:showAsAction="ifRoom"
android:icon="@android:drawable/ic_menu_share"
app:actionProviderClass="android.support.v7.widget.ShareActionProvider" />
</menu>
And this is the stacktrace I'm getting back:
java.lang.UnsupportedOperationException: This is not supported, use MenuItemCompat.setActionProvider()
at android.support.v7.internal.view.menu.MenuItemImpl.setActionProvider(MenuItemImpl.java:628)
at android.support.v7.internal.view.menu.MenuItemWrapperICS.setSupportActionProvider(MenuItemWrapperICS.java:315)
at android.support.v4.view.MenuItemCompat.setActionProvider(MenuItemCompat.java:345)
at android.support.v7.internal.view.SupportMenuInflater$MenuState.setItem(SupportMenuInflater.java:473)
at android.support.v7.internal.view.SupportMenuInflater$MenuState.addSubMenuItem(SupportMenuInflater.java:485)
at android.support.v7.internal.view.SupportMenuInflater.parseMenu(SupportMenuInflater.java:194)
at android.support.v7.internal.view.SupportMenuInflater.inflate(SupportMenuInflater.java:118)
at creativesdk.adobe.com.myapplication.MainActivity.onCreateActionMode(MainActivity.java:71)
at android.widget.AbsListView$MultiChoiceModeWrapper.onCreateActionMode(AbsListView.java:6165)
at android.support.v7.internal.view.SupportActionModeWrapper$CallbackWrapper.onCreateActionMode(SupportActionModeWrapper.java:151)
at android.support.v7.app.ActionBarActivityDelegateBase$ActionModeCallbackWrapper.onCreateActionMode(ActionBarActivityDelegateBase.java:1367)
at android.support.v7.internal.app.WindowDecorActionBar$ActionModeImpl.dispatchOnCreate(WindowDecorActionBar.java:1012)
at android.support.v7.internal.app.WindowDecorActionBar.startActionMode(WindowDecorActionBar.java:510)
at android.support.v7.app.ActionBarActivityDelegateBase.startSupportActionMode(ActionBarActivityDelegateBase.java:576)
at android.support.v7.app.ActionBarActivityDelegateHC.startActionModeForChild(ActionBarActivityDelegateHC.java:62)
at android.support.v7.internal.widget.NativeActionModeAwareLayout.startActionModeForChild(NativeActionModeAwareLayout.java:44)
at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:694)
at android.view.View.startActionMode(View.java:4857)
at android.widget.AbsListView.performLongPress(AbsListView.java:3102)
at android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:3061)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
I'm curious to know if anybody found the same problem and if there's a way around it.
There is indeed an issue on ICS devices when trying to inflate the menu item from the ActionMode with AppCompat v21. It seems the menu items are wrapped 2 times and a wrapped item method gets called instead of the native one, causing this Exception.
Google needs to fix this in a future version of AppCompat.
Anyway, here's a hack I implemented to make it work with the current release:
1) Create an utility class in the package android.support.v7.internal.view.menu
(using this package is mandatory to allow accessing package-protected methods without using reflection):
package android.support.v7.internal.view.menu;
import android.view.Menu;
/**
* Hack to allow inflating ActionMode menus on Android 4.0.x with AppCompat v21
*/
public class MenuUnwrapper {
public static Menu unwrap(Menu menu) {
if (menu instanceof MenuWrapperICS) {
return ((MenuWrapperICS) menu).getWrappedObject();
}
return menu;
}
}
2) Inflate your menu like this:
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.context_menu, MenuUnwrapper.unwrap(menu));
return true;
}
EDIT:
The bug has been fixed in AppCompat v21.0.2 and this hack is no longer necessary.
Update your tools.
Try this. It worked to me.
MenuItem menuItem = menu.findItem(R.id.search);
if (menuItem != null) {
MenuItemCompat.setOnActionExpandListener(menuItem,this);
MenuItemCompat.setActionView(menuItem, mSearchView);
}
Try this
inflater.inflate(R.menu.menu, menu);
// search
MenuItem item = menu.findItem(R.id.settings_search);
MenuItemCompat.setOnActionExpandListener(
item, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return true;
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With