I want to change one of my Action Bar Menu Tab Labels depending on the state of a variable in my code. I found the following that describes how to use onPrepareMenuOptions() for this purpose, but my problem is that onPrepareMenuOptions() is being called after I change the variable that controls the label state.
How can I alter a MenuItem on the Options Menu on Android?
As specific as I can be, I have a dialogFragment that's brought up when the user selects the relevant Action Bar item. The dialog allows the user to change a parameter, and depending on value selected, I want to change the AB item label (but not the code associated with either the AB item or the dialogFragment it starts up.
Is there something I should be doing (perhaps in the dialog's onDismiss() method) to force my application to call onPrepareMenuOptions()??
In response to Nate's request, my activity has the following code:
public boolean onCreateOptionsMenu (Menu menu)
{
getMenuInflater().inflate (R.menu.app_menu, menu);
this.abMenu = menu;
this.varTab = abMenu.findItem (R.id.menu_varTab);
// Need to be able to change this label
return super.onCreateOptionsMenu (menu);
}
#Override
public boolean onPrepareOptionsMenu (Menu menu)
{
varTab.setTitle (0 == importantVariable
? ("Set Var")
: ("Set Var\n" + String.valueOf (importantVariable)) + " units");
return super.onPrepareOptionsMenu (menu);
}
Following good advice, I added act.invalidateOptionsMenu() to the onDismiss() method of the dialogFragment associated with this menu item, and now the onPrepareOptionsMenu() is called when it should.
On Android 2.3.x and lower, the system calls onPrepareOptionsMenu() each time the user opens the options menu (presses the Menu button).
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().
I believe - if you are using tabs in your action bar, that something like this should work:
bar.getTabAt(0).setText("Some new Sequence");
Related
I get the menu item and then i try to set the visibility but the menu item is always shown. Can anyone see where I am making a mistake?
The menu item is not null and thus is allocated so thats not it.
MenuItem done = menu.findItem(R.id.action_done);
//animate the list view
if (isListEditing) {
done.setVisible(true);
menuItem.setTitle(this.getString(R.string.EditKey));
isListEditing = false;
adapter.endEdit();
} else {
done.setVisible(false);
menuItem.setTitle(this.getString(R.string.DoneKey));
isListEditing = true;
adapter.makeEditable();
}
this.invalidateOptionsMenu();
I get the menu reference here:
#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_test_results, menu);
this.menu = menu;
return true;
}
Update:
I was under the impression that you had to invalidate the options menu after you made an edit. But that is what was cause the edits to not go through.
According to the docs, what invalidateOptionsMenu() does is:
Declare that the options menu has changed, so should be recreated. The onCreateOptionsMenu(Menu) method will be called the next time it needs to be displayed.
That means onCreateOptionsMenu will get called again, inflating your original menu layout, and thus discarding your previous changes to the menu items visibility.
The recommended approach to modify the menu content dynamically is to use onPrepareOptionsMenu. So whenever you need to update menu items, you can call invalidateOptionsMenu(), and then inside onPrepareOptionsMenu, you set the menu items visibility.
There is no need for
this.invalidateOptionsMenu();
Take that off and it should work fine.
This works just fine but If I'm on a different activity and I use the back button, it won't update the action bar because the activity is already created and it won't update the action bar. Already tried to use supportInvalidateOptionsMenu() on the on_create method but it didn't work.
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
Cursor cursor = messages.getMessages();
if(cursor.getCount()>0){
inflater.inflate(R.menu.actionbar1, menu);
}else{
inflater.inflate(R.menu.actionbar2, menu);
}
return super.onCreateOptionsMenu(menu);
}
As the documentation for onCreateOptionsMenu(Menu) states:
This is only called once, the first time the options menu is
displayed. To update the menu every time it is displayed, see
onPrepareOptionsMenu(Menu).
So going back to an already created Activity does not trigger onCreateOptionsMenu(Menu) again.
What I suggest you to do is create just one menu containing all the menu items and selectively activate/deactivate them in onPrepareOptionsMenu(Menu) based on one or more flags. Then put invalidateOptionsMenu() in onResume() which is called every time the Activity is shown.
Hope it helps
Try calling invalidateOptionsMenu whenever you need to change the icon.
It will destroy your menus and re-inflate them by calling onPrepareOptionsMenu.
I have action bar and menu located in action bar.
When I touch hard menu button getActionBar() returns null.
Third at the bottom is what I mean with hard menu button:
I can prevent app to crash as: if(getActionBar() != null) { // ... }
But it's not what I want to do. I need the action bar items to modification (add/remove). So I am not able to do while getActionBar() returns null.
Anyone has any idea why getActionBar() returns null?
UPDATE:
Here is my code:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (getActionBar() != null) { // Action bar is null here when I click hard menu button.
getActionBar().setDisplayHomeAsUpEnabled(true);
}
// Some logical operations here.
// Get the menu.
BaseActivity.menuOnActionBar = menu;
return super.onCreateOptionsMenu(menu);
}
In my activity, after refresh completes I remove action view (action view was set to xml right after refresh clicked in order to show progress bar):
menuOnActionBar.findItem(R.id.menu_refresh).setActionView(null); // This throws an error.
And menuOnActionBar variable definition in BaseActivity:
public static Menu menuOnActionBar;
Thrown error is: E/AndroidRuntime(4193): java.lang.NullPointerException
I need the action bar items to modification (add/remove).
First, you do not need an ActionBar instance for that, as you cannot affect action bar items through ActionBar anyway. If you are adding or removing action bar items, call invalidateOptionsMenu() on your Activity, which will force Android to call onCreateOptionsMenu() again.
More importantly, you should not be doing that as a result of a MENU press, as by then it is too late. Instead, call invalidateOptionsMenu() when something changes in the state of your application that requires a change in the mix of action bar items.
If you need to change something else about the action bar (e.g., tabs), that is where getActionBar() becomes more relevant. Two scenarios in which I know that getActionBar() will return null are:
You do not have an action bar
You are extending an ActionBarSherlock class (e.g., SherlockActivity), in which case you need to be calling getSupportActionBar()
I would like to be able to append action bar items from my fragments.
For example in Landscape mode I have a list of items, and if clicked a page of information about that item appears.
The list can be changed by clicking the dropdown in the action bar to select a category of list.
Once a list item is clicked the details fragment is populated. I then want 3 tabs to be appended into the action bar so that the user can select which page of details is shown for that item, namely: "Details (default)";"Map"; and "Features".
In my fragment I can set setHasOptionsMenu(true) and then add the new tabs using the onCreateOptionsMenu call. This however deletes my dropdown which i still want displayed.
How does one simply append ActionBar Items..?
Thanks
I just call the fragment's onCreateOptionsMenu from my activity's onCreateOptionsMenu. You can add an if statement to decide to call the fragment's version or default call the fragment's onCreateOptionsMenu and put the if statement there to decide what to add. then, whenever it needs to change, just call invalidateOptionsMenu.
You will probably have to remove the setHasOptionsMenu call.
Activity:
public boolean onCreateOptionsMenu(Menu m)
{
// insert activity options
if (needFragmentOptions) {
fragment.onCreateOptionsMenu(m);
}
return true;
}
Fragment:
public boolean onCreateOptionsMenu(Menu m)
{
// insert fragment options
return true;
}
Do you know how to rename existing menu ?
I can rename when press menu item. But I don't know how to access to menu item when press the button.
Please advice.
It would be good if you can clarify the question a little, but each time the user presses the Menu on their Android device while inside one of your activities, the onPrepareOptionsMenu method is called. The first time the menu is shown (i.e. only once), the onCreateOptionsMenu method is called.
Basically, the onPrepareOptionsMenu method is where you should make any changes such as enabling/disabling certain menu items, or changing the menu item text depending on the circumstances.
As an example:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Check current message count
boolean haveMessages = mMessageCount != 0;
// Set 'delete' menu item state depending on count
MenuItem deleteItem = menu.findItem(R.id.menu_delete);
deleteItem.setTitle(haveMessages ? R.string.delete : R.string.no_messages);
deleteItem.setEnabled(haveMessages);
return super.onPrepareOptionsMenu(menu);
}
Use MenuItem.setTitle(). If this isn't what you needed, you have to be more specific.
The onPrepareOptionsMenu is the proper place to make changes to menuitems.