I have MainActivity and it's have fragment. I added toolbar from MainActivity;
MainActivity
private Toolbar mToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mToolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
When I was open any fragment from MainActivity then that fragment use own menu file
In fragment
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.custom_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
As you can see above I inflated custom menu in onCreateOptionsMenu. But It doesn't work.
after
toolbar.getMenu().clear();
add toolbar.inflateMenu(R.menu.menu_blank);
and I am not set toolbar as acionbar,Maybe you should user getActionbar to do something.
I'm not entirely sure this is what you're asking but I think you want to be able to change the options in the menu, dynamically. You can do the following
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
if (mHideSomething) {
MenuItem myItem = menu.findItem(R.id.action_something);
myItem.setVisible(false);
} //otherwise it will show as usual
return true;
}
Then when you want to change something in the menu...
mHideSomething = true;
supportInvalidateOptionsMenu();
EDIT
Now I understand you're just adding odd behaviour when overriding. You can still do the following (although it seems like these items just shouldn't be part of main menu if they're not relevant always)
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.custom_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
MenuItem mainMenuItemToRemove = menu.findItem(R.id.action_something);
mainMenuItemToRemove .setVisible(false);
}
The only problem with the above is it makes assumptions about what is available in the main menu even though the fragment should be reusable. A better solution would be to pass in an interface to the fragment to call back to the activity and let the activity have control. Better still, update the activity logic and never inflate the main menu at all if not required.
Related
I have an Activity with a Toolbar that I set as the supportActionBar. From this Activity I have various Fragments each with a customized ActionBar. I am able to call menu.clear() to remove the existing Menu but I am however unable to add another Menu in the same Fragment. This seems strange because menu.clear() behaves just as I would expect, but when calling inflater.inflate(R.menu.my_custom_menu,menu); appears to do nothing.
Example Fragment where I wish to modify the supportActionBar:
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
actionBar = ((AppCompatActivity)getActivity()).getSupportActionBar();
mGroupViewModel =
ViewModelProviders.of(requireActivity()).get(GroupsViewModel.class);
}
...
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
//Inflating seems to do nothing.
Log.i(TAG,"IN THE ONCREATEOPTIONSMENU FOR FRAGMENT.");
inflater.inflate(R.menu.group_edit_toolbar,menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
Log.i(TAG,"ONPREPARE OPTIONS MENU IN FRAGMENT.");
menu.clear();
super.onPrepareOptionsMenu(menu);
}
Clearly there is something I don't understand but I can't narrow down on what that problem is.
Would a better approach be to have each Fragment have their own Toolbar instead of all my fragments modifying the hosting activity's supportActionBar?
UPDATE
After further testing, I notice that if I try to assign a local MenuItem in my Fragment, I receive a null pointer exception unless I first inflate a menu in the Fragment itself. This is leading me to think that I am not hijacking control of the Activity's supportActionBar in the Fragment, but rather am trying to create a separate ActionBar for the Fragment. Would anyone be able to supplement my thinking here?
Fragment's menu callbacks:
MenuItem editItem;
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.i(TAG,"IN ONCREATEOPTIONS");
menu.clear();
//MUST INFLATE MENU OTHERWISE WE GET NULL ERROR.
inflater.inflate(R.menu.home_actionbar,menu);
editItem = menu.findItem(R.id.action_edit_group);
Log.i(TAG,"edititem: "+editItem.getItemId());
super.onCreateOptionsMenu(menu, inflater);
}
// This is called every time the Menu opens.
#Override
public void onPrepareOptionsMenu(Menu menu) {
Log.i(TAG,"IN THE on prepare FOR FRAGMENT.");
menu.findItem(R.id.action_create_group).setVisible(false);
menu.findItem(R.id.action_create_group).setEnabled(false);
if(owner.equals(currUser)){
menu.findItem(R.id.action_edit_group).setEnabled(true);
menu.findItem(R.id.action_edit_group).setVisible(true);
} else {
menu.findItem(R.id.action_edit_group).setVisible(false);
menu.findItem(R.id.action_edit_group).setEnabled(false);
}
super.onPrepareOptionsMenu(menu);
}
onPrepareOptionsMenu is always called after onCreateOptionsMenu and there you're deleting your recently inflated menu!
Just delete onPrepareOptionsMenu and it should work fine.
I am using drawerlayout in activity with several fragments. By clicking the navigation item, I switch the fragment this way:
switch (index) {
case 0:
if (checkinFragment == null) {
checkinFragment = new CheckinFragment();
ft.add(R.id.main_container, checkinFragment, "0");
} else {
ft.show(checkinFragment);
}
break;
case 3:
if (jianGuanFragment == null) {
jianGuanFragment = new JianGuanFragment();
ft.add(R.id.main_container, jianGuanFragment, "3");
} else {
ft.show(jianGuanFragment);
}
break;
}
ft.commitAllowingStateLoss();
Each fragment has a different menu resource file inflated in its onCreateOptionsMenu(Menu menu, MenuInflater inflater) method.
Steps:
1. When first enter the activity the menu in checkinFragment is shown.(All right)
2. Then switch to the jianGuanFragment, the menu in jianGuanFragment is shown.(Also right)
3. However, when switch back to the first fragment(checkinFragment), the actionbar menu isn't updated. The showing menu is still the one in jianGuanFragment. That's the problem.
And from the log I know the onCreateOptionsMenu in the showing fragment is called each time I switch to it. That's to say:
onCreateOptionsMenu is called but actionbar menu isn't updated.
Anyone can help me? Thanks a lot.
EDIT 1: add the code in onCreateOptionsMenu:
(1)in checkinFragment
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
LogUtils.e("TAG", "CheckinFragment onCreateOptionsMenu");
menu.clear();
inflater.inflate(R.menu.menu_setting, menu);
}
(2)in jianGuanFragment
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
LogUtils.e("TAG", "JianGuanFragment onCreateOptionsMenu");
menu.clear();
inflater.inflate(R.menu.menu_jianguan, menu);
}
EDIT 2: I use toolbar, not the old actionbar.
At last I find the solution:
Each time entering a fragment, re-set the toolbar as ationbar again.
#Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden) {
AppCompatActivity compatActivity = (AppCompatActivity) mActivity;
mToolbar = (Toolbar) compatActivity.findViewById(toolbarId);
compatActivity.setSupportActionBar(mToolbar);
}
}
Try this
1)in checkinFragment
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.clear();
LogUtils.e("TAG", "CheckinFragment onCreateOptionsMenu");
getActivity().getMenuInflater().inflate(R.menu.menu_setting, menu);
super.onPrepareOptionsMenu(menu);
}
Use invalidateOptionsMenu(). You need to use it where call to OnCreateOptionsMenu() is required.
EDIT:
getActivity().invalidateOptionsMenu() can be used if you want to call it from Fragment.
Hope that helps!!!
I want to have completely different menu options in different fragment.I followed this post.But my fragment menu is adding with the activity menu.But i don't want to have activity menus in some of my fragments.
In SlidingDrawerActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
In my fragment:
public Friends_Status_Comment_Fragment(){
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_add_comment,menu);
super.onCreateOptionsMenu(menu, inflater);
}
The Activities items are adding with the menu of fragment.How to stop it???
I'm not sure if I underestand your problem - in your fragment you should clear menu and create new one - and don't call super :) something like this:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
menu.clear();
inflater.inflate(R.menu.menu_add_comment,menu);
}
I have implemented ActionBar Navigation using Fragment. In my App i have one Activity and rest is in Fragments. In my MainActivity i am implementing menu like this.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
Two Fragments uses Navigation Drawer and in their respected fragments i am inflating menu buttons to sort items.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.sort_button_shops, menu);
}
Now the Problem is if i open the Fragment 1 it works perfectly. When i open fragment 2, it shows 2 button to sort, one from Fragment 1 and the second one from Fragment 2.
I have tried to hide the button but it didn't worked.
Any Help will be Appreciated.
Thanks
When you inflate a new menu you are adding new items to the old Menu object, which is probably not what you intended.
Try this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.removeItem(R.id.your_menu_item);
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
Try using this in onResume() of fragments.
MenuItem item = (MenuItem) findViewById(R.menu.activity_main);
item.setVisible(false);
this.invalidateOptionsMenu();
I'm using ActionBarSherlock in my project and sometimes need to add one or more items inside the action bar.
At this BaixadosFragment class (that extends SherlockFragment), I'm using the following code and it works fine:
#Override
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater)
{
inflater.inflate(R.menu.main, menu);
super.onCreateOptionsMenu(menu, inflater);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.refresh:
refresh();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
In this case, I'm adding a refresh button, witch is lonely inside main.xml
BUT I want to do the same at CupomDetalheActivity (though adding a share button), witch extends SherlockFragmentActivity instead. So I'm not able to override "onCreateOptionsMenu" as it has a different signature (below):
//this is inside SherlockFragmentActivity
public final boolean onCreateOptionsMenu(android.view.Menu menu) {
return true;
}
//this is inside SherlockFragment
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
//Nothing to see here.
}
Whith SherlockFragmentActivity, I don't even see where can I use the inflater to bring up the xml containing the share button...
I appreciate a lot any ideas and suggestions...
[EDIT] This worked, according to DroidT's suggestion:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.share, menu);
super.onCreateOptionsMenu(menu);
return true;
}
Your SherlockFragmentActivity also has an onCreateOptionsMenu() and onPrepareOptionsMenu(). You can inflate your menu options in the onCreateOptionsMenu() by using getSupportMenuInflater(). You would want to make a call to invalidateOptionsMenu() in your SherlockFragmentActivity whenever you want the change to happen and add the menu options in onPrepareOptionsMenu(). For more information look at the "Changing menu items at runtime" section of this link.
If you are using a menu inside of a fragment, make sure you call setHasOptionsMenu(true); in the fragments onCreate(Bundle savedInstance) method