Im looking to set an actionbar menu item visible from a helper class. Is it possible to access the actionbar Menu outside of onOptionsItemSelected through a reference to an activity? code below.
public boolean getMenuFromActivity(BaseActivity activity){
// something like Menu menu = activity.getActionBar().getMenu()?
// then get menu item by id and set visibility..
//return true if found
return false
}
Simple answer: Call findItem() on the Menu after you have inflated your menu resource in onCreateOptionsMenu(), and hold onto that MenuItem in a data member of your activity, so you can use it later.
Slightly less-simple answer: Hold onto the Menu from onCreateOptionsMenu() in a data member of your activity, and use it later to find your item.
Related
I have a Toolbar being used as an ActionBar with two items. I only want to ever display one at a time as they kind of replace each other. The problem is that when i replace a Fragment, it call onCreateOptionsMenu and will inflate the menu again, meaning that the same action button will be shown, even if the other one was previously in the ActionBar. I have to need to change anything in the ActionBar from my Fragments or when a new Fragment is displayed(with FragmentManager.FragmentTransaction.replace()). So my question is how do I not call onCreateOptionsMenu when a new fragment is displayed?
I can't use a boolean because I will still need it to reinflate on orientation change. And any advice on how to handle orentation change for my situation?
I can post code, but it seems more conceptual and I'm not sure that it would help.
I solved the problem by instead of not calling onCreateOptionsMenu, I added the items to my menu manually.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean refreshVisible;
if (refreshItem != null && refreshItem.isVisible()){//is being displayed prior to inflation
refreshVisible = true;
}else if (refreshItem == null){//it's null so the menu has never been created
refreshVisible = true;
}else {//it's not null and invisibe, other icon was being displayed
refreshVisible = false;
}
menu.clear();//clear menu so there are no duplicate or overlapping icons
getMenuInflater().inflate(R.menu.main, menu);//inflate menu
refreshItem = menu.findItem(R.id.refresh);
useDataItem = menu.findItem(R.id.use_data);
refreshItem.setVisible(refreshVisible);//if menu is being created for first time or item was previously visible, then display this item
useDataItem.setVisible(!refreshVisible);//display this item if not displaying other
return true;
}
I would fiddle with the onPrepareOptionsMenu hook. If you can detect that your menu should not be shown you should jest return false from there. Per documentation:
Prepare the Screen's standard options menu to be displayed. This is called right before the menu is shown, every time it is shown. You can use this method to efficiently enable/disable items or otherwise dynamically modify the contents.
and
You must return true for the menu to be displayed; if you return false it will not be shown.
You can call setHasOptionsMenu(false); inside your fragment.
This will prevent onCreateOptionsMenu() from being called when that fragment added.
I am trying to hide and show a menu item in my action bar.
when i click on the menu item, i run a function called showAddFrag(). Inside that function I am trying to hide the menu item. so my code is something like this
public void showAddFrag(){
Menu menu = new Menu (); // giving me this error: "Cannot instantiate the type Menu"
menu.findItem(R.id.add_item).setVisible(false); //hiding the add_item menu item
....
}
I know I am doing it wrong, but can someone point me in the right direction. Is there a function that I can reference to the context menu object?
Thanks in advance
You can use this callback: onPrepareOptionsMenu() and this method: menu.findItem(..) to save your button as an instance variable
Then set an onClickListener for your button that will disable it once clicked. And enable it back when you have to.
I hope this is what you're trying to do
I see that it's possible to handle a tap on a icon menĂ¹ item or by implementing
onOptionsItemSelected
inside the acivity, or by using
onMenuItemClickListener
like onclick listener on a button. When is better to use the fist one method, and when the second one?
Because for my opinion, using an external listener makes more modular the code, but create a new class, but using the first way don't create new class, but makes code less modular...
There are use cases other than the ones outlined below, but I'm putting in the general cases that come up regularly.
onOptionsItemSelected
If you're using Fragments, you may want to use onOptionsItemSelected and consider adding menu items to the Action Bar the way that is described in Adding items to the Action Bar.
What this describes is implementing onCreateOptionsMenu inside your Fragment. To make this happen, you must call setHasOptionsMenu in onCreate.
protected void onCreate(Bundle savedInstanceState) {
this.setHasOptionsMenu(true);
}
Setting this will actually make the Activity call onCreateOptionsMenu which allows you to add the menu items.
#Override
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
// add items corresponding to this Fragment
menu.add(...);
return true;
}
The reason I recommend this is that it allows you to put more of the menu handling code into your Fragment instead of the Activity to figure out which Fragment to call, etc.
In this case, clicking the menu item will call onOptionsItemSelected inside of your Fragment which I suggest.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.my_id1:
dothing1();
return true;
case R.id.my_id2:
dotghing2();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
More of a long winded answer, but this is the way to handle menu clicks inside your Fragment.
onMenuItemClickListener
In the case of onMenuItemClickListener, this is used when you DON'T want to use the pre-ready method above and implement your own.
What I mean by that is you implement OnMenuItemClickListener and generate the methods in the interface. You then assign the menu to call the Activity that implemented this where as the above option assumes what Activity to use based on the pre-ready implementation of the Activity to Fragment relationship.
If you are targeting API 14 or greater (ICS or above) you could implement an ActionProvider. If that's not an option then you could implement a base activity that will always populate the menu and handle any menu clicks using onOptionsItemSelected. This is a good approach to implement "About" or "Settings" menu items through all your activities.
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.