appcompat v21 throws java.lang.UnsupportedOperationException - android

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;
}
});

#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
Log.d(TAG, "onCreateActionMode");
MenuItem item = menu.findItem(R.id.menu_item_share);
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(item);
MenuItemCompat.setActionProvider(item, mShareActionProvider);
return true;
}

Related

getActionView returns null with searchview

Trying to get searchview to work on app.
sdk min 17 max 22
testing on emulator api 18
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/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never"/>
<item android:id="#+id/search"
android:icon="#drawable/ic_action_search"
android:title="#string/search_title"
app:showAsAction="ifRoom|collapseActionView"
android:orderInCategory="200"
app:actionViewClass="android.support.v7.widget.SearchView">
</item>
<item android:id="#+id/scan"
android:title="#string/scan"
android:showAsAction="ifRoom"
android:orderInCategory="300">
</item>
</menu>
onCreateOptionsMenu
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.material_toolbar, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
Log.d(TAG, "onQueryTextSubmit");
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
materialUpdate();
return false;
}
});
}
Running debug and looking at the search menu item shows action as null.
The layout display shows the android.support.v7.widget.SearchView as unknown xml attribute.
I am using Eclipse instead of Android Studio on this project.
Are you using Proguard or minify(ing) your code at some way?
https://code.google.com/p/android/issues/detail?id=58508
When you use a minify method like Proguard, classes and methods that you not access directly (but by some declarative way or reflexion) are removed. To avoid this, you need to instruct the build to specifically keep this classes/methods.
In this case, the SearchView class can be removed, because isn't directly called.
Try add this on your proguard rules file (check the right filename on your gradle file, at getDefaultProguardFile):
-keep class android.support.v7.widget.SearchView { *; }
This is how I added a SearchView to my menu (this is inside a Fragment):
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final MenuItem item = menu.add("Search");
item.setIcon(android.R.drawable.ic_menu_search);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
final SearchView searchView = new SearchView(getActivity());
searchView.setOnQueryTextListener(this);
searchView.setIconifiedByDefault(true);
item.setActionView(mSearchView);
}
As an aside, I'd also recommend making the switch to Android Studio.
You are using support library. Try this:
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_search));
// ...
return true;
}
Not sure exactly what was wrong with what I had. It all appeared to be logical. I suspect that I had some misspelling are xmlns that was not correct. But it works the way I have it.
I appreciate the help but recommend that answers explain what you believe the problem is, what the fix is and why. It really helps the person learn.
MenuItemCompat is helper for accessing features in MenuItem introduced after API level 4 in a backwards compatible fashion. It is not necessary for this scenario.
Please keep answering questions it really does help
Thanks

StackOverFlowError when trying to use action bar from support library

I have a very annoying problem, I was testing on Samsung (s3) device and every thing was working just fine, then I used LG device with OS 4.0 and When I try to open my application I got stackoverflowerror in the following method
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.actions_menu, menu);
}
My base activity extending ActionBarActivity from android.support.v7
can any one help please ?
EDIT 1
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.actions_menu, menu);
MenuItem editItem = menu.findItem(R.id.action_edit);
MenuItem saveItem = menu.findItem(R.id.action_save);
MenuItem deleteItem = menu.findItem(R.id.action_delete);
editItem.setVisible(isEditEnable());
saveItem.setVisible(isSaveEnable());
deleteItem.setVisible(isDeleteEnable());
invalidateOptionsMenu();
return true;
}
the exception occurred in getMenuInflater().inflate(R.menu.actions_menu, menu);
Looks like you calling return onCreateOptionsMenu(); after inflation the menu.
instead just use return true;
update:
You're calling invalidateOptionsMenu(); which i think will call onCreateOptionsMenu() again.
Remove it and change your menu in onPrepareOptionMenu(), there is no need to call invalidateOptionsMenu()

SearchView (Support) in FragmentActivity always null

I've started messing around with fragments, as my app on tablets could be using space more efficiently.
Now, in my old app, I had a SearchView in the actionbar menu, that would show on ifRoom. I'm using the same code, but now the SearchView item is always null. I'm not looking for changing the menu items depending on active fragments or whatever, I just need the SearchView to function from the FragmentActivity.
FragmentActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.svPet);
this.svPet = (SearchView)MenuItemCompat.getActionView(searchItem);
if(this.svPet != null)
{
this.svPet.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
this.svPet.setOnQueryTextListener(this);
}
return true;
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/svPet"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"
android:title="#string/search"
android:titleCondensed="#string/search">
</item>
...Some more items that are never shown as action and work correctly
</menu>
So, whenever the menu is being created, this.svPet stays null, the searchview is not displayed in the bar (even when there's more than enough room), and when I click on the item from the menu, my application crashes, saying there's a nullpointer on
this.svPet.setIconified(false);
in
#Override
public boolean onOptionsItemSelected(MenuItem item)
Any ideas on what might be wrong? I'm probably overlooking something, but I just don't see what's wrong at the moment. Thanks in advance :)
some ideas
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
//SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
SearchView searchView = (SearchView) searchItem.getActionView();
if (searchView != null) {
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
// do something with s, the entered string
query = s;
Toast.makeText(getApplicationContext(), "String entered is " + s,Toast.LENGTH_SHORT).show();
return true;
}
#Override
public boolean onQueryTextChange(String s) {
return false;
}
});
}
return super.onCreateOptionsMenu(menu);
}
menu.xml
<item android:id="#+id/action_search"
android:orderInCategory="5"
android:title="Search"
android:icon="#drawable/ic_action_search"
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.widget.SearchView" />
</menu>
So... after some digging I found that when using MenuItemCompat in combination with FragmentActivity, getActionView(searchItem) returns null. I think this is a bug in the support library, so I'll have to submit a bugreport for that. (Done, https://code.google.com/p/android/issues/detail?id=76141&thanks=76141&ts=1410649918)
My workaround:
Instead of
this.svPet = (SearchView)MenuItemCompat.getActionView(searchItem);
I used
this.svPet = new SearchView(this);
MenuItemCompat.setShowAsAction(searchItem, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
MenuItemCompat.setActionView(searchItem, this.svPet);
--Edit--
After some more looking around, I found that you can just use ActionBarActivity instead of FragmentActivity, as ActionBarActivity extends FragmentActivity. When using that, you can use
this.svPet = (SearchView)MenuItemCompat.getActionView(searchItem);
as usual.

getActionProvider: item does not implement SupportMenuItem

I am trying to implement a ShareActionProvider using the support library in a contextual action bar in my fragment. I face no issues implementing it in a normal action bar( onCreateOptionsMenu() ), but when i try it in the CAB ( onCreateActionMode() in MultiModeListener interface), I get the error :
getActionProvider: item does not implement SupportMenuItem; returning null
Looking at the Android source at https://cells-source.cs.columbia.edu/plugins/gitiles/platform/frameworks/support/+/30837f1095c803f332f4a1c3f0917c8afdd50156/v4/java/android/support/v4/view/MenuItemCompat.java, the problem seems to be because my MenuItem is not an instance of SupportMenuItem :
public static ActionProvider getActionProvider(MenuItem item) {
if (item instanceof SupportMenuItem) {
return ((SupportMenuItem) item).getSupportActionProvider();
}
// TODO Wrap the framework ActionProvider and return it
Log.w(TAG, "getActionProvider: item does not implement SupportMenuItem; returning null");
return null;
}
Any ideas on how i can go about resolving this ?
Manifest :
<activity
android:name=".myactivity_ActionBarActivity"
android:theme="#style/Theme.AppCompat.Light"
android:windowSoftInputMode="stateUnchanged">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Activity :
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
public class myactivity_ActionBarActivity extends ActionBarActivity{
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.actionbaractivity_layout); //loads a fragment
}
}
fragment :
import android.support.v7.widget.ShareActionProvider;
import android.support.v4.view.MenuItemCompat;
import android.view.MenuItem;
import android.view.Menu;
import android.support.v4.app.Fragment;
...
...
#Override
public void onActivityCreated(Bundle savedInstanceState) {
...
...
//Handle Action mode events
myListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
private ShareActionProvider mShareActonProvider;
....
....
#Override
public boolean onCreateActionMode(ActionMode mode,
Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.chatsession_contextmenu, menu);
//get the ShareActionProvider from the menu item
MenuItem item = menu.findItem(R.id.share_menu);
mShareActonProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(item);
return true;
}
}
...
...
}
Menu layout file :
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/delete_menu"
android:title="Delete message"
myapp:showAsAction="ifRoom|withText"
android:icon="#drawable/ic_action_discard">
</item>
<item
android:id="#+id/share_menu"
android:title="Share message"
myapp:showAsAction="ifRoom|withText"
android:icon="#drawable/ic_action_share"
myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider">
</item>
</menu>
Edit 1 :
The root of the problem seems to be the difference in the Menu object that is being passed as argument to onCreateActionMode(ActionMode mode, Menu menu) and onCreateOptionsMenu(Menu menu, MenuInflater inflater). Only the one in onCreateOptionsMenu has the MenuWrapperICS. Here is a screenshot of both objects in debug mode :
onCreateActionMode(ActionMode mode, Menu menu) :
onCreateOptionsMenu(Menu menu, MenuInflater inflater) :
The problem is that the MultipleModeListener interface extends the android.view.ActionMode.Callback, as can be seen in the source code at http://androidxref.com/4.4.2_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#6301. If you are using ShareActionProvider from the support library, you need the android.support.v7.view.ActionMode.Callback instead.
The solution is to create your own ActionMode.CallBack implementation instead of using the framework's MultipleModeListener. This way you make sure that the support libraries are being used wherever required.
For example :
Import the v7 version of ActionMode and ActionBarActivity in your fragment
import android.support.v7.view.ActionMode;
import android.support.v7.app.ActionBarActivity;
Create an onClickListener for your list view and use startSupportActionMode to start your custom ActionMode.CallBack implementation
myListView.setItemsCanFocus(false);
myListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
actionMode = null;
myListView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
if(myListView.getCheckedItemCount() == 0){
actionMode.finish();
return;
}
if(actionMode == null){
actionMode = ((ActionBarActivity)getActivity()).startSupportActionMode(new ContextualActionBar());
}
}
});
Create your custom ActionMode.Callback implementation
private class ContextualActionBar implements ActionMode.Callback{
private ShareActionProvider mShareActionProvider;
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch(item.getItemId()){
case R.id.share_menu :
mode.finish();
return true;
default :
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.chatsession_contextmenu, menu);
//Initialize the ShareActionProvider
MenuItem shareMenuItem = menu.findItem(R.id.share_menu);
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareMenuItem);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, "test message");
mShareActionProvider.setShareIntent(shareIntent);
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
//Nullify the actionMode object
//so that the onClickListener can identify whether the ActionMode is ON
actionMode = null;
//Uncheck all checked messages
SparseBooleanArray selectedItems = myListView.getCheckedItemPositions();
for(int i=0;i<selectedItems.size();i++){
myListView.setItemChecked(selectedItems.keyAt(i), false);
}
}
#Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
// TODO Auto-generated method stub
return false;
}
}
Be careful to use the right MenuInflater when populating the IMenu in onCreateActionMode. When I use the one from the mode object, as you do in your fragment class, it doesn't create the support version of ShareActionProvider. I switched to using the MenuInflater from the parent AppCompatActivity class and it worked fine.
Given that the mode object is from the support library, one would assume it would use the support inflater, but apparently not.
Are you sure that your activity extends ActionBarActivity?
I had an almost identical setup. The problem in my case was that Proguard was optimizing away the constructor of the ShareActionProvider. There is a bug that they while they do keep the class and methods of ActionProvider classes detected in your XML, they don't keep the constructors or the class name.
If you have a "Cannot instantiate class" warning in your log, then this would apply to you, too.
Here is the Android bug report that helped me.
And the proguard config I added was:
-keepnames public class * extends android.support.v4.view.ActionProvider
-keepclassmembers public class * extends android.support.v4.view.ActionProvider {
<init>(android.content.Context);
}

How to disable/hide three-dot indicator(Option menu indicator) on ICS handsets

How to disable/hide three-dot indicator(Option menu indicator) on ICS handsets which does't have menu button. ?
I am running application as <uses-sdk android:minSdkVersion="5"/> in Manifest, code is compiled with 4.0. Three-dot indicator shows on every screen.
Example for preference activities i don't want show Three-dot indicator, since it does't have any menu options.
Adding android:targetSdkVersion="14" in manifest it works. However don't want hide/remove three dots button on all screens . Only in preference activities don't want to show this three dots button.
Override onPrepareOptionsMenu() in the fragment of the preference with this:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item= menu.findItem(R.id.menu_settings);
item.setVisible(false);
super.onPrepareOptionsMenu(menu);
return true;
}
if you have more then one item set all the items visibility flag to false
and add the command setHasOptionsMenu(true);
to the onCreate command
after you will set all the visibility of the items to false the menu will disappear
on activity, the only difference is the onPrepareOptionsMenu is boolean and you don't need to add the setHasOptionsMenu(true); command on the creation
I just deleted the method :
#Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
getSupportMenuInflater().inflate(R.menu.main, menu);
return true;
}
then that three-dot-menu goes away (:
Hope it helps.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return false;
}
There is no way to show/hide "three-dot" menu indicator for a single activity. You can hide this menu indicator only for entire app by specifying android:targetSdkVersion="14" (or above) in your manifest file.
However, this menu indicator is not showing on preferences activity if it extends from native android.preference.PreferenceActivity class. I have this scenario implemented in a few of my apps, and it works perfectly.
I assume you are using some custom preferences implementations which does not extends from PreferenceActivity. Android Dev Team suggests to always use PreferenceActivity for any preferences in your applications.
Way too late to the party here, I was trying to remove all my menu items and the 3-dots(option menu indicator), I did differently than the solution given here I am surprised that nobody had told it. There is a visibility tag that can be set to false and no changing of code in activity is required visibility=false does the trick
in res / menu /..
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
visibility=false
android:title="#string/action_settings"/>
override method and return false remember of not call super
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return false;
}
Remove this item in res / menu / main.xml
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/action_settings"/>
In addition: do not add an item that has showAsAction="never"- this will avoid the dots from showing. If you have more items than can not be shown at once the dots will be there again (and they are items that are flagged ifRoom).
Following code worked for my app. Tried on Samsung Galaxy S4 (Android 4.3) and Nexus 4 (Android 4.2):
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item= menu.findItem(R.id.action_settings);
item.setVisible(false);
return true;
}
for hiding 3 dots in actionbar/ toolbar
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_dash_board_drawer, menu);
return false; //for visible 3 dots change to true, hiding false
}
You can actually change the Android targetVersion thus forcing the 3-dot menu to either hide or show. You need to override onCreate of your Activity like this :
#Override
public void onCreate(Bundle savedInstanceState) {
getApplicationInfo().targetSdkVersion = 10; // To enable the 3-dot menu call this code before super.OnCreate
super.onCreate(savedInstanceState);
}
#Override
public void onCreate(Bundle savedInstanceState) {
getApplicationInfo().targetSdkVersion = 14; // To disable the 3-dot menu call this code before super.OnCreate
super.onCreate(savedInstanceState);
}
Tested on Android 4.x.x and Android 3.0
I just excluded the "onCreateOptionsMenu"-method:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
//Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_planos, menu);
return true;
}
If you simply want to hide the button, this solution is a bit of a hack but works across all versions of Android (using AppCompat) and doesn't affect your other menu items:
styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light">
...
<item name="android:actionOverflowButtonStyle">#style/AppTheme.Overflow</item>
<!-- If you're using AppCompat, instead use -->
<item name="actionOverflowButtonStyle">#style/AppTheme.Overflow</item>
</style>
<style name="AppTheme" />
<style name="AppTheme.Overflow">
<item name="android:src">#null</item>
</style>
If you want the Overflow button hidden only on some screens, you could make this an alternate theme (change AppTheme above to AppTheme.NoOverflow) that only certain activities use :
AndroidManifest.xml
<activity android:name=".NoOverflowActivity"
android:theme="#style/AppTheme.NoOverflow" >
This effectively just makes the icon have no width and height. I rarely recommend opposing design guidelines but in my scenario we used dedicated hardware that did not properly report a menu button was present.
Just want to improve #war_hero answer.
If You wanna set the visibility on run time You can use oncreateoptions menu parameter like this
Menu overflow;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.mymenu, menu);
this.overflow = menu;
return super.onCreateOptionsMenu(menu);
}
and then make a function to show or hide any menu item according to the index. for e.g.
public void hideorShowMenuItems(boolean bool){
overflow.getItem(1).setVisible(bool);
overflow.getItem(2).setVisible(bool);
overflow.getItem(3).setVisible(bool);
overflow.getItem(4).setVisible(bool);
overflow.getItem(5).setVisible(bool);
}
Copy paste this code in main.xml in menu folder
you just need to make the item android:visible="false"
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:visible="false"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
Should be:
<item
android:id="#+id/linearlayout_splash"
android:orderInCategory="100"
android:showAsAction="never"
android:visible="false"
android:title="#string/action_settings"/>
If MainActivity is
public class MainActivity extends AppCompatActivity
In MainActivity Class, Remove the below code.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
Do it like this.
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// if nav drawer is opened, hide the action items
boolean drawerOpen = mDrawerLayout.isDrawerOpen(leftDrawer);
return (!drawerOpen);
}
I am checking if my navigation drawer is visible I will hide the menu and vice versa. You can use it according to you requirement. Hope this helps. Happy Coding. :)
This is how I find a solution of mine. It maybe helpful.
#Override
public boolean onKeyDown(int keycode, KeyEvent event ) {
//KEYCODE_MENU
if(keycode == KeyEvent.KEYCODE_MENU){
/* AlertDialog.Builder dialogBuilder
= new AlertDialog.Builder(this)
.setMessage("Test")
.setTitle("Menu dialog");
dialogBuilder.create().show();*/
return true;
// finish();
}
return super.onKeyDown(keycode,event);
}
I just used
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
Where R.menu.main is only an empty menu xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" ></menu>

Categories

Resources