How dynamically add contents to menu item? [duplicate] - android

I'm trying to change the title of a menu item from outside of the onOptionsItemSelected(MenuItem item) method.
I already do the following;
public boolean onOptionsItemSelected(MenuItem item) {
try {
switch(item.getItemId()) {
case R.id.bedSwitch:
if(item.getTitle().equals("Set to 'In bed'")) {
item.setTitle("Set to 'Out of bed'");
inBed = false;
} else {
item.setTitle("Set to 'In bed'");
inBed = true;
}
break;
}
} catch(Exception e) {
Log.i("Sleep Recorder", e.toString());
}
return true;
}
however I'd like to be able to modify the title of a particular menu item outside of this method.

I would suggest keeping a reference within the activity to the Menu object you receive in onCreateOptionsMenu and then using that to retrieve the MenuItem that requires the change as and when you need it. For example, you could do something along the lines of the following:
public class YourActivity extends Activity {
private Menu menu;
private String inBedMenuTitle = "Set to 'In bed'";
private String outOfBedMenuTitle = "Set to 'Out of bed'";
private boolean inBed = false;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Create your menu...
this.menu = menu;
return true;
}
private void updateMenuTitles() {
MenuItem bedMenuItem = menu.findItem(R.id.bedSwitch);
if (inBed) {
bedMenuItem.setTitle(outOfBedMenuTitle);
} else {
bedMenuItem.setTitle(inBedMenuTitle);
}
}
}
Alternatively, you can override onPrepareOptionsMenu to update the menu items each time the menu is displayed.

As JxDarkAngel suggested, calling this from anywhere in your Activity,
invalidateOptionsMenu();
and then overriding:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.bedSwitch);
if (item.getTitle().equals("Set to 'In bed'")) {
item.setTitle("Set to 'Out of bed'");
inBed = false;
} else {
item.setTitle("Set to 'In bed'");
inBed = true;
}
return super.onPrepareOptionsMenu(menu);
}
is a much better choice. I used the answer from https://stackoverflow.com/a/17496503/568197

you can do this create a global "Menu" object then assign it in onCreateOptionMenu
public class ExampleActivity extends AppCompatActivity
Menu menu;
then assign here
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
this.menu = menu;
return true;
}
Then later use assigned Menu object to get required items
menu.findItem(R.id.bedSwitch).setTitle("Your Text");

Create a setOptionsTitle() method and set a field in your class. Such as:
String bedStatus = "Set to 'Out of Bed'";
...
public void setOptionsTitle(String status)
{
bedStatus = status;
}
Now when the menu gets populated, change the title to whatever your status is:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(bedStatus);
// Return true so that the menu gets displayed.
return true;
}

You better use the override onPrepareOptionsMenu
menu.Clear ();
if (TabActual == TabSelec.Anuncio)
{
menu.Add(10, 11, 0, "Crear anuncio");
menu.Add(10, 12, 1, "Modificar anuncio");
menu.Add(10, 13, 2, "Eliminar anuncio");
menu.Add(10, 14, 3, "Actualizar");
}
if (TabActual == TabSelec.Fotos)
{
menu.Add(20, 21, 0, "Subir foto");
menu.Add(20, 22, 1, "Actualizar");
}
if (TabActual == TabSelec.Comentarios)
{
menu.Add(30, 31, 0, "Actualizar");
}
Here an example

I use this code to costum my bottom navigation item
BottomNavigationView navigation = this.findViewById(R.id.my_bottom_navigation);
Menu menu = navigation.getMenu();
menu.findItem(R.id.nav_wall_see).setTitle("Hello");

Declare your menu field.
private Menu menu;
Following is onCreateOptionsMenu() method
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
try {
getMenuInflater().inflate(R.menu.menu_main,menu);
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "onCreateOptionsMenu: error: "+e.getMessage());
}
return super.onCreateOptionsMenu(menu);
}
Following will be your name setter activity. Either through a button click or through conditional code
public void setMenuName(){
menu.findItem(R.id.menuItemId).setTitle(/*Set your desired menu title here*/);
}
This worked for me.

You can do it like this, and no need to dedicate variable:
Toolbar toolbar = findViewById(R.id.toolbar);
Menu menu = toolbar.getMenu();
MenuItem menuItem = menu.findItem(R.id.some_action);
menuItem.setTitle("New title");
Or a little simplified:
MenuItem menuItem = ((Toolbar)findViewById(R.id.toolbar)).getMenu().findItem(R.id.some_action);
menuItem.setTitle("New title");
It works only - after the menu created.

You can Change Menu Item text using below Code: -
fun showPopup(v: View) {
popup = PopupMenu(context, v)
val inflater = popup?.menuInflater
popup?.setOnMenuItemClickListener(this)
inflater?.inflate(R.menu.menu_main, popup?.menu)
val menu: Menu = popup!!.menu
val item = menu.findItem(R.id.name)
if (item.title.equals("Name")) {
item.title = "Safal Bhatia"
}
}

It seems to me that you want to change the contents of menu inside a local method, and this method is called at any time, whenever an event is occurred, or in the activity UI thread.
Why don't you take the instance of Menu in the global variable in onPrepareOptionsMenu when this is overridden and use in this method of yours. Be sure that this method is called whenever an event is occurred (like button click), or in the activity UI thread, handler or async-task post-execute.
You should know in advance the index of this menu item you want to change. After clearing the menu, you need to inflate the menu XML and update your item's name or icon.

For people that need the title set statically.
This can be done in the AndroidManifest.xml
<activity
android:name=".ActivityName"
android:label="Title Text" >
</activity>

I needed to change the menu icon for the fragment. I altered Charles’s answer to this question a bit for the fragment:
private Menu top_menu;
//...
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
//...
rootview = inflater.inflate(R.layout.first_content,null);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu, menu);
this.top_menu = menu;
}
// my procedure
private void updateIconMenu() {
if(top_menu!= null) {
MenuItem nav_undo = top_menu.findItem(R.id.action_undo);
nav_undo.setIcon( R.drawable.back);
}
}

I hit this problem too. In my case I wanted to set the string to
reflect additional information using getString.
As stated above you need to find the correct menuItem in the menu and set it in the onPrepareOptionsMenu method. The solutions above didn't handle the case where the item was in a sub menu and for this you need to search the submenu for the item. I wrote a little Kotlin recursive function to allow me to this for multiple items. Code below...
override fun onPrepareOptionsMenu(menu: Menu) {
...
menu.menuSetText(R.id.add_new_card,
getString(R.string.add_card, currentDeck.deckName))
...
}
private fun Menu.getMenuItem(idx: Int, itemId: Int): MenuItem? {
Log.d(TAG, "getMenuItem: $idx of ${this.size()}")
if (idx >= size()) return null
val item = getItem(idx)
if (item.hasSubMenu()) {
val mi = item.subMenu.getMenuItem(0, itemId)
// mi non-null means we found item.
if (mi != null)
return mi
}
if (item != null && item.itemId == itemId)
return item
return getMenuItem(idx + 1, itemId)
}
fun Menu.menuSetText(itemId: Int, title: String) {
val menuItem = getMenuItem(0, itemId)
if (menuItem != null)
menuItem.title = title
else
Log.e(TAG,
"menuSetText to \"$title\": Failed to find ${
"itemId:0x%08x".format(itemId)}"
)
}

Related

Xamarin Android: ActionBar SearchView ActionView returns null

I'm using the ActionBar menu as:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/menu_search"
android:actionViewClass="com.abc.AppSearchView"
android:icon="#drawable/ic_menu_search"
android:showAsAction="always|collapseActionView" />
</menu>
Then I inflate it and :
public override bool OnCreateOptionsMenu (IMenu menu)
{
MenuInflater.Inflate (Resource.Menu.actionMenu, menu);
_actionBarMenu = menu;
// Get the SearchView and set the searchable configuration
var searchManager = (SearchManager)GetSystemService (SearchService);
var searchMenuItem = menu.FindItem (Resource.Id.menu_search);
var searchView = (AppSearchView)searchMenuItem.ActionView;
// Assumes current activity is the searchable activity
searchView.SetSearchableInfo (searchManager.GetSearchableInfo (ComponentName));
searchView.SetSearchViewListener (this);
return base.OnCreateOptionsMenu (menu);
}
I have a custom Search View implementation:
public class AppSearchView : SearchView
{
private IAppSearchViewListener mListener;
public AppSearchView (Context ctxt) : base (ctxt)
{
}
public override void OnActionViewCollapsed ()
{
if (mListener != null)
mListener.OnSearchViewCollapsed (this);
base.OnActionViewCollapsed ();
}
public override void OnActionViewExpanded ()
{
if (mListener != null)
mListener.OnSearchViewExpanded (this);
base.OnActionViewExpanded ();
}
public interface IAppSearchViewListener
{
void OnSearchViewCollapsed (SearchView sView);
void OnSearchViewExpanded (SearchView sView);
}
public void SetSearchViewListener (IAppSearchViewListener listener)
{
mListener = listener;
}
}
The searchMenuItem.ActionView is null (Consequently, search view is null). But this same code works in another application I have. Both applications are using Xamarin.Android.Support.v13.
Also, if I use android.widget.SearchView, it works fine and ActionView is not null.
Could someone please shed some light on the same?
Problem is that you are trying to cast a Java type into a .NET type. This only works for some types.
Instead in your OnCreateOptionsMenu implementation you will need to use .JavaCast<T>() extension method to help you.
Something like this works for me:
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.main, menu);
var item = menu.FindItem(Resource.Id.action_search);
var searchView = MenuItemCompat.GetActionView(item);
_searchView = searchView.JavaCast<SearchView>();
_searchView.QueryTextChange += (s, e) => _adapter.Filter.InvokeFilter(e.NewText);
_searchView.QueryTextSubmit += (s, e) =>
{
// Handle enter/search button on keyboard here
Toast.MakeText(this, "Searched for: " + e.Query, ToastLength.Short).Show();
e.Handled = true;
};
MenuItemCompat.SetOnActionExpandListener(item, new SearchViewExpandListener(_adapter));
return true;
}
This is the SearchViewExpandListener:
private class SearchViewExpandListener
: Java.Lang.Object, MenuItemCompat.IOnActionExpandListener
{
private readonly IFilterable _adapter;
public SearchViewExpandListener(IFilterable adapter)
{
_adapter = adapter;
}
public bool OnMenuItemActionCollapse(IMenuItem item)
{
_adapter.Filter.InvokeFilter("");
return true;
}
public bool OnMenuItemActionExpand(IMenuItem item)
{
return true;
}
}
EDIT:
Ok so the above answer is still relevant, which shows the usage with Support v7. Either way, the new version of Xamarin.Android explicity specifies that, all views and types that you are going to reference in you AXML/XML files, need to use [Register("my.view.Name")]. If you don't do this, when the app is compiled a checksum is used, instead of your namespace as was used previously, for your package name. This means that you will never be able to find the view.
So in your custom AppSearchView class you need to add the RegisterAttributeFlags like:
[Register("com.abc.AppSearchView)]
public class AppSearchView : SearchView
{
}
Now you should be able to find the ActionView.
More information about the breaking changes of Xamarin.Android 5 can be read on the forums.

Android: Showing Action Bar menu items depending on ViewPager

I am having trouble getting the following piece of code to work out. I have a viewpager with 3 fragments, and I want a search icon to only show up on one. I started off trying to add the search function by the fragment, but the rendering of the menu item was slow when swiping to that page. I am now on the part to add the search icon to the activity, and then just hide or show depending on which viewpager page is active, but the following is not working:
public class MyApp extends FragmentActivity implements
FragmentTeams.FragmentNotification,ViewPager.OnPageChangeListener,
OnNavigationListener{
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
menuSearch = menu.findItem(R.id.menu_search);
mSearchView = new SearchView(this);
menuSearch.setActionView(mSearchView);
menuSearch.setVisible(false);
return true;
}
#Override
public void onPageSelected(int pageNum) {
if(pageNum== 1){
ActionBar actionBar = MyApp.this.getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
menuSearch.setVisible(true);
invalidateOptionsMenu();
}else{
ActionBar actionBar = MyApp.this.getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
menuSearch.setVisible(false);
invalidateOptionsMenu();
}
}
While the above does (appear to) create and hide the icon at onCreateOptionsMenu, it is not reenabled when moving to
pageNum ==1
Can anyone give me some insight as to why this may be happening?
invalidateOptionsMenu make the system calls the method onPrepareOptionsMenu, so you can override this method as follows:
public boolean onPrepareOptionsMenu(Menu menu) {
int pageNum = getCurrentPage();
if (pageNum == 1) {
menu.findItem(R.id.menu_search).setVisible(true);
}
else {
menu.findItem(R.id.menu_search).setVisible(false);
}
}
public void onPageSelected(int pageNum) {
invalidateOptionsMenu();
}
You can implement onCreateOptionsMenu() in your Fragment and set 'setHasOptionsMenu(true)' for the fragment
a possible solution for this problem would be inflating your custom menu inside the activity hosts your ViewPager and getting a menu reference as below:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.custom_menu, menu);
customMenu = menu;
return super.onCreateOptionsMenu(menu);
}
after that you can easily hide/show the menu's items without any delay inside onPageSelected method as below:
#Override
public void onPageSelected(int position) {
switch (position) {
case 0: {
customMenu.getItem(0).setVisible(false);
break;
}
case 1: {
customMenu.getItem(0).setVisible(true);
break;
}
}
I used Nermeen's answer and managed to get it without any delay.
I don't inflate anything in onCreateOptionsMenu, but use it to get a reference to the menu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
customMenu = menu;
return super.onCreateOptionsMenu(menu);
}
Then, in onPrepareOptionsMenu(), I call the viewpager getCurrentItem() (should be something like viewPager.getCurrentItem()), call invalidateOptionsMenu() and inflate whatever menu I want in that page using the customMenu reference I created in onCreateOptionsMenu().

Can I change the Icon on an Actionbar Item

I'm not trying to change the main Icon , just a menu item's icon.
The Icon is essentially displays whether I am recording at that moment. I change the icon when it's tapped using
item.setIcon(R.drawable.recordstart);
In this method.
public boolean onOptionsItemSelected(MenuItem item) {
...
} else if (item.getItemId() == R.id.ab_menu_VRecord) {
if(recording)
{
item.setIcon(R.drawable.recordstop);
}else{
item.setIcon(R.drawable.recordstart);
}
}
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
Anyone know how I can do this outside this method.
Example:
class {
public MenuItem example;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.actionbar, menu);
example = menu.findItem(R.id.ab_menu_exampleview);
return true;
}
}
Then throughout your class you can use
example.setIcon("Your Image");
Not 100% sure where you are wanting to change the icon, but you can certainly cache or create a class member variable and point it at the the MenuItem in your Activity or Fragment for example. After they click it or you inflate it, assign it to the member variable and when you need to change it, you've got a reference or "cached" pointer to it to change the icon.
I think that is a UI change so you might have to be sure that you only call that on the UI thread.
if(!item.isChecked()){
item.setChecked(true);
item.setIcon(R.drawable.icon1);
}else{
item.setChecked(false);
item.setIcon(R.drawable.icon2);
}
is this?

Android : Get view Reference to a Menu Item

I plan to use quick actions UI pattern in my application. Android Quick Actions UI Pattern . The quick action window needs a pivot view to stick to.
quickAction.show(View pivotView);
I intend to use quick action for the menu Item, I can get access to the item that is clicked.
But the problem is i need to reference a view from the menu item so that i can pass it to the quick action.
How can i get reference to a view in the menuItem that is selected.
You can achieve this by providing your menu item with an actionViewClass property in xml and then you will be able to get the pivot view u wanted. The code would be something like this
<item
android:id="#+id/menu_find"
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.ImageButton"
/>
In your OnCreateOptionsMenu do this
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_search, menu);
locButton = (ImageButton) menu.findItem(R.id.menu_find).getActionView();
locButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
createPopup();
mQuickAction.show(v);
}
});
return true;
}
Old question, but I ran into some issues with the actionViewClass attribute. For anyone who runs into this later...
Calling findViewById(R.id.mnu_item) in onOptionsItemSelected will return a View anchor.
QuickActions on the MenuItems aren't good design, but I found that they are the simplest way to implement submenus with custom backgrounds.
Inorder to get reference Views of menu items we need to do this,
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.section, menu);
new Handler().post(new Runnable() {
#Override
public void run() {
final View menuItemView = findViewById(R.id.action_preview);
// SOME OF YOUR TASK AFTER GETTING VIEW REFERENCE
}
});
return true;
}
An update for anyone that want to find the menu view item for other reasons (like I wanted).
If you have access to and use AppCompat's Toolbar there is a way. It's not the most efficient way, but it's the easiest way I've found to access the menu item's view.
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
// Find Menu
for (int toolbarChildIndex = 0; toolbarChildIndex < toolbar.getChildCount(); toolbarChildIndex++) {
View view = toolbar.getChildAt(toolbarChildIndex);
// Found Menu
if (view instanceof ActionMenuView) {
ActionMenuView menuView = (ActionMenuView) view;
// All menu items
for (int menuChildIndex = 0; menuChildIndex < menuView.getChildCount(); menuChildIndex++) {
ActionMenuItemView itemView = (ActionMenuItemView) menuView.getChildAt(menuChildIndex);
// Do something to itemView...
}
}
}
}
Universal code which also works on Android 10
/**
* pass toolbar and menu item id, i.e. R.id.menu_refresh
*/
#Nullable
#Throws(
IllegalAccessException::class,
NoSuchFieldException::class
)
fun getMenuItemView(toolbar: Toolbar?, #IdRes menuItemId: Int): View? {
val mMenuView: Field = Toolbar::class.java.getDeclaredField("mMenuView")
mMenuView.setAccessible(true)
val menuView: Any? = mMenuView.get(toolbar)
(menuView as ViewGroup).children.forEach {
if(it.id == menuItemId) {
return it
}
}
return null
}
in the main activity class, best to override the onOptionsItemSelected(...) method; should be something as below:
public boolean onOptionsItemSelected(MenuItem item) {
// the id is of type int
int someId = item.getItemId();
// can use an if() or switch() statement to check if id is selected
//a Toast message can be used to show item is selected
}
Kotlin!!
override fun onCreateOptionsMenu(Menu menu): Boolean {
/*Adding menu items to action bar*/
menuInflater.inflate(R.menu.main, menu)
/*Getting menu item*/
val locButton: MenuItem = menu.findItem(R.id.menu_find)
/*Creating click listener*/
locButton.setOnMenuItemClickListener{
/*TODO: Handle it*/
true
}
return true;
}

Android: How to enable/disable option menu item on button click?

I can easily do it when I am using onCreateOptionsMenu or onOptionsItemSelected methods.
But I have a button somewhere in screen, and on clicking that button, it should enable/disable context menu items.
Anyway, the documentation covers all the things.
Changing menu items at runtime
Once the activity is created, the
onCreateOptionsMenu() method is called
only once, as described above. The
system keeps and re-uses the Menu you
define in this method until your
activity is destroyed. If you want to
change the Options Menu any time after
it's first created, you must override
the onPrepareOptionsMenu() method.
This passes you the Menu object as it
currently exists. This is useful if
you'd like to remove, add, disable, or
enable menu items depending on the
current state of your application.
E.g.
#Override
public boolean onPrepareOptionsMenu (Menu menu) {
if (isFinalized) {
menu.getItem(1).setEnabled(false);
// You can also use something like:
// menu.findItem(R.id.example_foobar).setEnabled(false);
}
return true;
}
On Android 3.0 and higher, the options menu is considered to always be open when menu items are presented in the action bar. When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().
On all android versions, easiest way: use this to SHOW a menu action icon as disabled AND make it FUNCTION as disabled as well:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.menu_my_item);
if (myItemShouldBeEnabled) {
item.setEnabled(true);
item.getIcon().setAlpha(255);
} else {
// disabled
item.setEnabled(false);
item.getIcon().setAlpha(130);
}
}
You could save the item as a variable when creating the option menu and then change its properties at will.
private MenuItem securedConnection;
private MenuItem insecuredConnection;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.connect_menu, menu);
securedConnection = menu.getItem(0);
insecuredConnection = menu.getItem(1);
return true;
}
public void foo(){
securedConnection.setEnabled(true);
}
How to update the current menu in order to enable or disable the items when an AsyncTask is done.
In my use case I needed to disable my menu while my AsyncTask was loading data, then after loading all the data, I needed to enable all the menu again in order to let the user use it.
This prevented the app to let users click on menu items while data was loading.
First, I declare a state variable , if the variable is 0 the menu is shown, if that variable is 1 the menu is hidden.
private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.
Then in my onCreateOptionsMenu() I check for this variable , if it's 1 I disable all my items, if not, I just show them all
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_galeria_pictos, menu);
if(mMenuState==1){
for (int i = 0; i < menu.size(); i++) {
menu.getItem(i).setVisible(false);
}
}else{
for (int i = 0; i < menu.size(); i++) {
menu.getItem(i).setVisible(true);
}
}
return super.onCreateOptionsMenu(menu);
}
Now, when my Activity starts, onCreateOptionsMenu() will be called just once, and all my items will be gone because I set up the state for them at the start.
Then I create an AsyncTask Where I set that state variable to 0 in my onPostExecute()
This step is very important!
When you call invalidateOptionsMenu(); it will relaunch onCreateOptionsMenu();
So, after setting up my state to 0, I just redraw all the menu but this time with my variable on 0 , that said, all the menu will be shown after all the asynchronous process is done, and then my user can use the menu.
public class LoadMyGroups extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mMenuState = 1; //you can set here the state of the menu too if you dont want to initialize it at global declaration.
}
#Override
protected Void doInBackground(Void... voids) {
//Background work
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mMenuState=0; //We change the state and relaunch onCreateOptionsMenu
invalidateOptionsMenu(); //Relaunch onCreateOptionsMenu
}
}
Results
simplify #Vikas version
#Override
public boolean onPrepareOptionsMenu (Menu menu) {
menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
return true;
}
A more modern answer for an old question:
MainActivity.kt
private var myMenuIconEnabled by Delegates.observable(true) { _, old, new ->
if (new != old) invalidateOptionsMenu()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.my_button).setOnClickListener { myMenuIconEnabled = false }
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main_activity, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
menu.findItem(R.id.action_my_action).isEnabled = myMenuIconEnabled
return super.onPrepareOptionsMenu(menu)
}
menu_main_activity.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/action_my_action"
android:icon="#drawable/ic_my_icon_24dp"
app:iconTint="#drawable/menu_item_icon_selector"
android:title="My title"
app:showAsAction="always" />
</menu>
menu_item_icon_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?enabledMenuIconColor" android:state_enabled="true" />
<item android:color="?disabledMenuIconColor" />
attrs.xml
<resources>
<attr name="enabledMenuIconColor" format="reference|color"/>
<attr name="disabledMenuIconColor" format="reference|color"/>
</resources>
styles.xml or themes.xml
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="disabledMenuIconColor">#color/white_30_alpha</item>
<item name="enabledMenuIconColor">#android:color/white</item>
What I did was save a reference to the Menu at onCreateOptionsMenu. This is similar to nir's answer except instead of saving each individual item, I saved the entire menu.
Declare a Menu Menu toolbarMenu;.
Then in onCreateOptionsMenusave the menu to your variable
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
toolbarMenu = menu;
return true;
}
Now you can access your menu and all of its items anytime you want.
toolbarMenu.getItem(0).setEnabled(false);
the best solution
when you are perform on navigation drawer
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(0,false);
return true;
}
If visible menu
menu.findItem(R.id.id_name).setVisible(true);
If hide menu
menu.findItem(R.id.id_name).setVisible(false);
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_id:
//Your Code....
item.setEnabled(false);
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.home, menu);
return false;
}
Generally can change the properties of your views in runtime:
(Button) item = (Button) findViewById(R.id.idBut);
and then...
item.setVisibility(false)
but
if you want to modify de visibility of the options from the ContextMenu, on press your button, you can activate a flag, and then in onCreateContextMenu you can do something like this:
#Override
public void onCreateContextMenu(ContextMenu menu,
View v,ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle(R.string.context_title);
if (flagIsOn()) {
addMenuItem(menu, "Option available", true);
} else {
Toast.makeText(this, "Option not available", 500).show();
}
}
I hope this helps

Categories

Resources