ActionBar tabs and onPrepareOptionsMenu behaviour - android

My app uses tab navigation with Actionbar Sherlock to switch between two fragments each with their own listview. Also, each fragment has it's own options menu associated with it, so within my two fragment classes I've made use of:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
...
}
For one of the fragments, its important to have some of the options in its options menu greyed out depending on which items the user has selected in its list. I've done this by calling:
#Override
public void onPrepareOptionsMenu(Menu menu){
...
}
Within this method, I identify which items in the list have been checked. I've noticed that when I switch between tabs, onPrepareOptionsMenu get called right away. Then the very next time I press the menu key, onPrepareOptionsMenu is not called, and the available options in the menu are not updated. When I hit the menu button a second time, everything works fine and the available options get updated. Is there I way I can enforce onPrepareOptionsMenu gets called when the menu key is pressed following a tab switch?
I've seen notes about using invalidateOptionsMenu() to trigger onPrepareOptionsMenu, but it seems messy to override the menu key event every time while this issue only comes up the first time the user presses the menu key. Is there a better way?

Related

Android - Settings menu of the main activity

I have a settings menu item that is generated in MainActivity. All the MainActivity's job is to contain fragments that actually do the job. Those fragments have their own action bar items and they work as expected.
The settings menu item should show/hide, depending on a certain condition that is changing between fragments, so assuming the code is on MainActivity, it should be:
if (condition) menu.findItem(R.id.action_settings).setVisible(false);
else menu.findItem(R.id.action_settings).setVisible(true);
Now I'm wondering where should I place the code because the condition changes between fragments but the actual menu item is on MainActivity.
Your condition might be OK and you can put it in your Activity's onPrepareOptionsMenu().
As you said this gets called just one time when you enter the Activity (with some exceptions).
You need to force the system to recall the Activity onPrepareOptionsMenu() when switching through fragments, and that is done - from anywhere - with the line invalidateOptionsMenu() (or, if necessary, getActivity().invalidateOptionsMenu()).
Good points to paste it might be Fragments onResume(), or any other point at which you think your condition state has changed.
Depending on your libraries, there's also a support method for API<11 called supportInvalidateOptionsMenu().
This should be called each time you want your Menu to change. However, if your fragments just add some items to a base, activity menu, take a look at this.
i think it is gonna work for you
public boolean onPrepareOptionsMenu(Menu menu) {
// if nav drawer is opened, hide the action items
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}

Android: hide action bar menu views regardless the menu items

I am using navigation drawer to switch between fragments.
And my action bar menu items are different regarding to the fragments.
I want to hide the menu item views when drawer is opened.
Referring to the doc, it suggest to find the menu item by ID and hide the item.
However, my menu items are different with fragments, so, how can I simply hide/show the menu item views on the action bar? Is there some flag to control it?
By the way, I see in the DOC it says I can return false in onPrepareOptionsMenu() to make it not displayed, however I tried and ended up in vain. Did I misunderstand it?
public boolean onPrepareOptionsMenu (Menu menu)
Added in API level 1
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.
The default implementation updates the system menu items based on the activity's state. Deriving classes should always call through to the base class implementation.
Parameters
menu The options menu as last shown or first initialized by onCreateOptionsMenu().
Returns
You must return true for the menu to be displayed; if you return false it will not be shown.
If people are still visiting the link, this is how we disable the options menu or options menu items for a fragment.
1) In the onCreateView() method of fragment add the following code
setHasOptionsMenu(true);// then only we can work with the menu items.Without this onPrepareOptionsMenu() method is not called
.
Now override the onPreparedOptionsMenu() method and hide the menu items. If you hide all the menu items the menu will not at all be shown. or use menu.clear() to clear all the menu items
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(R.id.menu_contacts).setVisible(false);
--------------
}

ActionBarCompat + tabs: remove Fragment Menu Item when switching?

For each Fragment I will add Menu Items to provide the user with context related actions. But when switching to another Fragment, the Menu items stayed. So I can end with all options from each fragment in the menu.
How do you clean the menu item to have only the ones set up in the activity menu?
I read about invalidateOptionMenu() and onPrepareOPtionmenu() but I don't really get how they work. What is the correct way to implement it ?
Anyway, how is it that removing fragment-linked menu item when the fragment is not displayed anymore is not native Android behavior?
EDIT if instrucitons not clear enough.
I have one activity supporting Navigation_Mode_Tabs with settings as global menu item.
I start fragA that add itemA1 and itemA2. So I have setting, itemA1, itemA2. So far, so good.
Then I switch to fragB that add its own itemB. HERE, I have settings, itemA1, itemA2, itemB in the menu !
Why itemA1 and itemA2 are stuck? How to remove them?
EDIT 2 : I have try another set up of tabulation from this post and it suddenly menu items seems to be correctly remove !
It's something to see with the use of remove(R.id.container, fragment) versus the onDetach()/onAttach() that Google recommands here
I am looking at this, probably tomorrow I'll update. Please, if you know about this, share :)
you could set the menuinflater on each activity.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.demo, menu);
return true;
}
You should add TabListener to your tabs and call supportInvalidateOptionsMenu() in onTabSelected() method. It cause call onCreateOptionsMenu(). You should override it in your activity and inflate menu for selected fragment. If you add menu items from code don't forget to clear menu for previous fragment.

fragment menu items not showing correctly on swipe but will show on tab select - no menu xml

I have an activity with 5 fragments. I am using a FragmentPageAdapter from the support library to achieve swiping.
Fragment4 needs to have an additional menu item added to the action bar. I can get this working fine, ONLY if the user selects the tab and doesn't swipe to it. If the user swipes to the tab the additional menu item does not show all the time.
Essentially, when i swipe to Fragment3, the menu item will show (because Fragment4's onCreateView is called and stored into memory), it stays when i swipe to Fragment4 (the one intended to have the menu item) and then disappears again when i swipe to Fragment5 (which it should do). However, it stays gone unless I swipe all the back to Fragment2 and then proceed forward. The only exception being that if I am at least 2 fragments away and select the tab, then it will correctly show the menu item for Fragment4.
Also, if it is showing the menu item from Fragment3 because it is calling the onCreate at that point in execution, why does it then disappear when swiping to Fragment5? It is my understanding that the FragmentPageAdapter has 3 fragments 'loaded' at one time to enable the smooth swiping feature..
Please see code below.
public View onCreateView(){
..
setHasOptionsMenu(true);
..
return view;
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
SubMenu sub = menu.addSubMenu("Options");
sub.add(0, EMAIL, 0, "Email");
sub.add(0, FILTER, 0, "Filter");
sub.add(0, SAVE, 0, "Save");
sub.getItem().setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
setMenuVisibility(true);
}
if I add setMenuVisibility(true) to onActivityCreated the menu will show when the previous fragment comes into view because that is technically when MyFragment.onActivityCreated is called, so then the menu is showing for the correct tab and the previous tab. However, if i swipe past the MyFragment tab the menu disappears and will not reappear when swiping back the the MyFragment tab or any other tab. The documentation about onCreateOptionsMenu 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 I tried adding
public void onPrepareOptionsMenu(Menu menu){
setMenuVisibility(true);
}
but it has no effect at all. I am obviously missing something here... this should work
EDIT:
Ok, so the more I look into ActionBarSherlock, the more it seems that this behavior is only available using that library. It does not appear to be part of the 'native' action bar/FragmentPagerAdapter behavior for any version of Android. Can anyone confirm this for me?
I experienced the same issues as you did, menu icons did show on tab select but not on swipe. This solution worked for me:
Click
see johanols comment.
Your other issue seems strange to me. Why not keep all 5 fragments loaded?
mViewPager.setOffscreenPageLimit(5);
Hope it helps :)

How to disable a particular option from optionmenu across all the tabs in android?

I am developing an application which consists of four tabs. Its also having six optionmenu which is common to all the four tabs and I need to disable one of the option menu depending on the current state of the application. Is there any way to disable particular option from the optionmenu across all the tabs??
To disable a menu item, you can override onPrepareOptionsMenu in your activity:
public boolean onPrepareOptionsMenu(Menu menu) {
// To disable the item
menu.findItem(R.id.the_menu_id).setEnabled(false);
// To make the item invisible
menu.findItem(R.id.the_menu_id).setVisibility(false);
}
If your tabs are composed of multiple views, then you only need to override the method in one place. If your tabs are composed of multiple activities, then you'll need to override the method in each of your activities and choose which items to display based on your application's state.

Categories

Resources