Inflate Android Menu - android

I have an activity with a ViewPager object (with two pages). The first page should not show any menu. But the second one should show a menu with one item.
The problem is, if I inflate the menu in the onCreateOptionsMenu with any menu.xml, everything work nice, I mean, the menu changes when I change the ViewPager's page ... but I don't want tho show any menu in the first page.
So, I thought not to inflate the menu in onCreateOptionsMenu(by this way, I will not show any menu in the first page, and I will inflate it when I show the second page), but if I don't inflate the menu in the onCreateOptionsMenu, the menu is not shown anymore!
Here is my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.item_list_activity);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
if (position == 1) {
//Show user's menu
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.configure_users_menu, mMenu);
} else if (position == 0) {
//Clear menu. Don't show nothing.
mMenu.clear();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//If I don't inflate the menu here, the menu does not inflate anymore.
//If I inflate the menu here (with any menu), the menu works nice.
/*MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.configure_groups_menu, menu);*/
mMenu = menu;
return true;
}
I've tried to use menu.clear() after inflate the menu in the onCreateOptionsMenu, but it does not work.
Thanks a lot!!

You should not be inflating menu's yourself, only do this in the onCreateOptionsMenu method.
This is wrong:
#Override
public void onPageSelected(int position) {
if (position == 1) {
//Show user's menu
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.configure_users_menu, mMenu);
} else if (position == 0) {
//Clear menu. Don't show nothing.
mMenu.clear();
}
}
I created a step by step guide on how to achieve the "per page menu". This method will automatically hide and show menu's per Fragment (page). (Assuming your mAppSectionsPagerAdapter contains Fragments)
Step 1:
Don't inflate any menu's in your Activity, but if you do those menu items will always be shown.
Step 2:
Call the setHasOptionsMenu method in the onCreate of the Fragment with the menu
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Step 3:
Inflate the menu for the page (Fragment), do this inside the fragment code! Because the setHasOptionsMenu has been set to true the menu will be shown, but only if the fragment is active in the pager.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
//TODO Inflate menu here!
super.onCreateOptionsMenu(menu, inflater);
}
Full example code (Randomly googled): http://www.java2s.com/Code/Android/UI/Demonstrateshowfragmentscanparticipateintheoptionsmenu.htm

Related

Add Menu to Activity's supportToolBar from a Fragment

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.

Duplicate Menu and Data in Fragments after using FragmentStatePagerAdapter

I tried so many answers provided by various posts here but nothing worked for me.
Problem- I have navigation drawer that has 6 fragments but single activity. Everything worked fine till I changed 1st ranked fragment in drawer. I wanted Swipe tabs inside first fragment. So I used FragmentStatePagerAdapter.
Each fragment has its own menu along with MainActivity Menu.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Notify the system to allow an options menu for this fragment.
setHasOptionsMenu(true);
}
And inflated like this:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.story, menu);
}
Everything works fine. But When I visit other fragments in navigation drawer then it shows duplicate menu in toolbar. It creates more duplicates if there is space left in toolbar when I visit other fragments.
Try 1 : To solve this problem I initially used:
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.clear();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.story, menu);
}
With this I don't get duplicate menu but now I don't see MainActivity menus.
Try 2:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
getActivity().invalidateOptionsMenu();
inflater.inflate(R.menu.story, menu);
}
With this I get both Fragment and Activity menu but Duplicates are there.
This should be easy to solve but I am not picking up a way to deal with this. Maybe I didn't understand the life cycle well?
My other approach- Implementing all menus in Fragments will do the trick but this should be our last option.
Solution to this - To maintain both Menu all I have to do is this (Very easy solution):
menu.clear();
inflater.inflate(R.menu.story, menu);
getActivity().getMenuInflater().inflate(R.menu.main, menu);
Problem 2 OnOptionsItemSelected method from 1st fragment is getting called in other fragments.
private void hideAllMenuItems() {
if (actionBarMenu != null) {
actionBarMenu.findItem(R.id.action_item1).setVisible(false);
actionBarMenu.findItem(R.id.action_item2).setVisible(false);
}
}
private void showMenuIcon() {
if (actionBarMenu != null) {
hideAllMenuItems();
if (currentFragment instanceof Fragment1)
actionBarMenu.findItem(R.id.action_item1).setVisible(true);
else if (currentFragment instanceof Fragment2)
actionBarMenu.findItem(R.id.action_item2).setVisible(true);
}
}
call shoeMenuIcon() each time new fragment load..
Hope you are looking for this

Hide MenuItem in one Fragment in FragmentActivity with swipe tabs functionality

I've a FragmentActivity with three swipe tabs. I've added a REFRESH Icon as MenuItem in actionbar and inflated that menu in FragmentActivity by overriding onCreateOptionsMenu.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
getMenuInflater().inflate(R.menu.live_stream_item, menu);
refreshMenuItem = (MenuItem) menu.getItem(0);
refreshMenuItem.setVisible(true);
return super.onCreateOptionsMenu(menu);
}
I've globally declared refreshMenuItem and wanted to set Visibility GONE refreshMenuItem.setVisible(false) in one fragment and make it visible in other fragments.
I've used setHasOptionsMenu in one fragment where I want refresh menu item Invisible.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(false);
}
Even I tried to set that refreshMenuItem.setVisible(false) in setUserVisibleHint in that particular fragment to hide this menuItem.
Nothing works.....Please help me out.
set setHasOptionsMenu(true) in Fragment's onCreate method and
override the onPrepareOptionsMenu() in the fragment and set the visibility of the corresponding menu item.
#Override
void onPrepareOptionsMenu(Menu menu) {
// if nav drawer is opened, hide the action items
menu.findItem(R.id.xxx).setVisible(false);
menu.findItem(R.id.yyy).setVisible(false);
}

Hide/Show Action Bar Option Menu Item for different fragments

I have a Sherlock Fragment Activity in which there are 3 Fragments.
Fragment A, Fragment B, Fragment C are three fragments. I want to show a done option menu in Fragment B only.
And the activity is started with Fragment A. When Fragment B is selected done button is added.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if(!menusInflated){
inflater.inflate(R.menu.security, menu);
menusInflated=true;
}
super.onCreateOptionsMenu(menu, inflater);
}
When I again start Fragment A I want to options Menu DONE (which was set at Fragment B) for this I am doing like this
setHasOptionsMenu(false);
MenuItem item = (MenuItem) menu.findItem(R.id.done_item);
item.setVisible(false);
But this is not hiding at all, also it is giving NullPointerException when Activity if first started with Fragment A.
Please let me know what is the problem.
Try this...
You don't need to override onCreateOptionsMenu() in your Fragment class again. Menu items visibility can be changed by overriding onPrepareOptionsMenu() method available in Fragment class.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_search).setVisible(false);
super.onPrepareOptionsMenu(menu);
}
This is one way of doing this:
add a "group" to your menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group
android:id="#+id/main_menu_group">
<item android:id="#+id/done_item"
android:title="..."
android:icon="..."
android:showAsAction="..."/>
</group>
</menu>
then, add a
Menu menu;
variable to your activity and set it in your override of onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
// inflate your menu here
}
After, add and use this function to your activity when you'd like to show/hide the menu:
public void showOverflowMenu(boolean showMenu){
if(menu == null)
return;
menu.setGroupVisible(R.id.main_menu_group, showMenu);
}
I am not saying this is the best/only way, but it works well for me.
To show action items (action buttons) in the ActionBar of fragments where they are only needed, do this:
Lets say you want the save button to only show in the fragment where you accept input for items and not in the Fragment where you view a list of items, add this to the OnCreateOptionsMenu method of the Fragment where you view the items:
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (menu != null) {
menu.findItem(R.id.action_save_item).setVisible(false);
}
}
NOTE: For this to work, you need the onCreate() method in your Fragment (where you want to hide item button, the item view fragment in our example) and add setHasOptionsMenu(true) like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Might not be the best option, but it works and it's simple.
This will work for sure I guess...
// Declare
Menu menu;
MenuItem menuDoneItem;
// Then in your onCreateOptionMenu() method write the following...
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
this.menu=menu;
inflater.inflate(R.menu.secutity, menu);
}
// In your onOptionItemSelected() method write the following...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.done_item:
this.menuDoneItem=item;
someOperation();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// Now Making invisible any menu item...
public void menuInvisible(){
setHasOptionsMenu(true);// Take part in populating the action bar menu
menuDoneItem=(MenuItem)menu.findItem(R.id.done_item);
menuRefresh.setVisible(false); // make true to make the menu item visible.
}
//Use the above method whenever you need to make your menu item visible or invisiable
You can also refer this link for more details, it is a very useful one.
MenuItem Import = menu.findItem(R.id.Import);
Import.setVisible(false)
Try this
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.custom_actionbar, menu);
menu.setGroupVisible(...);
}
By setting the Visibility of all items in Menu, the appbar menu or overflow menu will be Hide automatically
Example
private Menu menu_change_language;
...
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
...
...
menu_change_language = menu;
menu_change_language.findItem(R.id.menu_change_language).setVisible(true);
return super.onCreateOptionsMenu(menu);
}
Before going to other fragment use bellow code:
if(menu_change_language != null){
menu_change_language.findItem(R.id.menu_change_language)
.setVisible(false);
}
Hello I got the best solution of this, suppose if u have to hide a particular item at on create Menu method and show that item in other fragment. I am taking an example of two menu item one is edit and other is delete. e.g menu xml is as given below:
sell_menu.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_edit"
android:icon="#drawable/ic_edit_white_shadow_24dp"
app:showAsAction="always"
android:title="Edit" />
<item
android:id="#+id/action_delete"
android:icon="#drawable/ic_delete_white_shadow_24dp"
app:showAsAction="always"
android:title="Delete" />
Now Override the two method in your activity & make a field variable mMenu as:
private Menu mMenu; // field variable
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sell_menu, menu);
this.mMenu = menu;
menu.findItem(R.id.action_delete).setVisible(false);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_delete) {
// do action
return true;
} else if (item.getItemId() == R.id.action_edit) {
// do action
return true;
}
return super.onOptionsItemSelected(item);
}
Make two following method in your Activity & call them from fragment to hide and show your menu item. These method are as:
public void showDeleteImageOption(boolean status) {
if (menu != null) {
menu.findItem(R.id.action_delete).setVisible(status);
}
}
public void showEditImageOption(boolean status) {
if (menu != null) {
menu.findItem(R.id.action_edit).setVisible(status);
}
}
That's Solve from my side,I think this explanation will help you.
You can make a menu for each fragment, and a global variable that mark which fragment is in use now.
and check the value of the variable in onCreateOptionsMenu and inflate the correct menu
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (fragment_it == 6) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.custom_actionbar, menu);
}
}
Okay I spend couple of hour to get this solution.apparently you can get menuitem from your toolbar to anywhere in activity or fragment. So in my case.
var menuItem = toolbar.menu;
Now to get specfic item from menu item
favIcon = menuItem.findItem(R.id.favourite);
Note: favIcon is MenuItem declare global
Now if you can do whatever you want to do for this icon
eg. to make it invisible
favIcon?.isVisible=false
Even though the question is old and answered. There is a simpler answer to that than the above mentioned. You don't need to use any other variables.
You can create the buttons on action bar whatever the fragment you want, instead of doing the visibility stuff(show/hide).
Add the following in the fragment whatever u need the menu item.
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Sample menu.xml file:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_addFlat"
android:icon="#drawable/add"
android:showAsAction="ifRoom|withText"
android:title="#string/action_addFlat"/>
</menu>
Handling onclick events is as usual.
Late to the party but the answers above didn't seem to work for me.
My first tab fragment (uses getChildFragmentManager() for inner tabs) has the menu to show a search icon and uses android.support.v7.widget.SearchView to search within the inner tab fragment but navigating to other tabs (which also have inner tabs using getChildFragmentManager()) would not remove the search icon (as not required) and therefore still accessible with no function, maybe as I am using the below (ie outer main tabs with each inner tabs)
getChildFragmentManager();
However I use the below in my fragments containing/using the getChildFragmentManager() for inner tabs.
//region onCreate
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
//access setHasOptionsMenu()
setHasOptionsMenu(true);
}
//endregion onCreate
and then clear the menu item inside onPrepareOptionsMenu for fragments(search icon & functions)
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
//clear the menu/hide the icon & disable the search access/function ...
//this will clear the menu entirely, so rewrite/draw the menu items after if needed
menu.clear();
}
Works well and navigating back to the tab/inner tab with the search icon functions re displays the search icon & functions.
Hope this helps...
For some reason the method was not working for me this is how I solved it according to the accepted solution
//This should be in on create
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
showOverflowMenu(false);
}
},100);
#Override
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
getMenuInflater().inflate(R.menu.options_menu, menu);
return true;
}
public void showOverflowMenu(boolean showMenu){
if(menu == null)
return;
menu.setGroupVisible(R.id.grp, showMenu);
}

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().

Categories

Resources