12

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?

Zombie
  • 1,965
  • 2
  • 20
  • 34
Josh
  • 2,685
  • 6
  • 33
  • 47

4 Answers4

22

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();
}
Mustafa Berkay Mutlu
  • 1,929
  • 1
  • 25
  • 37
Nermeen
  • 15,883
  • 5
  • 59
  • 72
  • 1
    Thanks for the quick response! This does work correctly. However, there is still a slight delay from the time I swipe to a page and the rendering of the menu items. I am going to follow up by studying the stock Google apps, as it seems they render instantly. – Josh Nov 05 '12 at 10:28
  • 1
    If you use support library then its `supportInvalidateOptionsMenu()` – IronBlossom Jun 25 '14 at 05:42
  • 1
    Well I am not able to find the getCurrentPage() method, is it userdefined or of Android itself? – Pravinsingh Waghela Jan 28 '15 at 13:03
4

You can implement onCreateOptionsMenu() in your Fragment and set 'setHasOptionsMenu(true)' for the fragment

Boy
  • 7,010
  • 4
  • 54
  • 68
  • I did this and it works on some devices; but on other devices it only works when you go to the next page and go back (it does not work the first time) – Roel Nov 03 '14 at 15:13
  • That is weird...feels like bugs in the specific implementation of those devices...damn manufacturers... – Boy Nov 05 '14 at 10:59
0

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;
        }
     }
Moaz H
  • 776
  • 1
  • 6
  • 5
0

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