3

I have a ViewPager with fragments in my Android app. I want to show Action Bar menu item depending the fragment of the ViewPager. I have readen some questions about this but I can´t find the correct solution. My ViewPager´s code is this:

public class My_Activity extends ActionBarActivity {

    private ViewPager mViewPager;
    String idioma;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_main);

        ActionBar actionBar = getSupportActionBar(); // || getActionBar();
        actionBar.setIcon(getResources().getDrawable(R.drawable.navbar_logo));
        actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#CC3333")));

        actionBar.setTitle("Hello");

        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        PagerTabStrip pagerTabStrip = (PagerTabStrip) findViewById(R.id.pagerTabStrip);
        pagerTabStrip.setTabIndicatorColor(getResources().getColor(R.color.blanco));

        Title_Liga_Adapter titleAdapter = new Title_Liga_Adapter(getSupportFragmentManager());
        mViewPager.setAdapter(titleAdapter);

        mViewPager.setCurrentItem(0);

        getSupportActionBar().setIcon(R.drawable.navbar_logo);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (mViewPager.getCurrentItem() == 4) {
            getMenuInflater().inflate(R.menu.menu_comunidad,
                                      menu);
        } else {

        }
        return true;
    }

    /* *
     * Called when invalidateOptionsMenu() is triggered
     */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {

        menu.findItem(R.id.action_search)
            .setVisible(true);

        return super.onPrepareOptionsMenu(menu);
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            // Respond to the action bar's Up/Home button
            case android.R.id.home:
                this.finish();
                return true;

            case R.id.action_search:

                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

}

I want that when CurrentItem is 4 for example show menu items icons.

DragonFire
  • 3,722
  • 2
  • 38
  • 51
Elena
  • 181
  • 2
  • 12
  • You can implement OnPageChangeListener http://developer.android.com/reference/android/support/v4/view/ViewPager.OnPageChangeListener.html and you can do what ever you want to do in onPageSelected function. – Nauman Afzaal Feb 05 '15 at 11:08
  • I have updated my code with the onPageChangeListener, but how I create the menu inside this? Thanks – Elena Feb 05 '15 at 11:23
  • By calling invalidateOptionMenu function onCreateOptionMenu will be called here you can inflate menu according to visible page – Nauman Afzaal Feb 05 '15 at 11:31
  • By calling invalidateOptionMenu function onCreateOptionMenu will be called here you can inflate menu according to visible page like this MenuInflater inflater=getMenuInflater(); inflater.inflate(R.menu.menu,menu); – Nauman Afzaal Feb 05 '15 at 11:31
  • Sorry I don´t speak very well english, where I have to call invalidateOptionsMenu? Can you put example code? Sorry. – Elena Feb 05 '15 at 11:39

4 Answers4

7

First create addOnPageChangeListener in onCreate method

ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
           // ...

    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            invalidateOptionsMenu();
        }

        @Override
        public void onPageSelected(int position) {

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
}

Then you override onCreateOptionMenu()

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    if (mViewPager.getCurrentItem()==0){
        menu.findItem(R.id.action_search).setVisible(true);
    } else if(mViewPager.getCurrentItem()==1){
        menu.findItem(R.id.action_search).setVisible(false);
    } else if(mViewPager.getCurrentItem()==2){
        // configure
    } else if(mViewPager.getCurrentItem()==3){
        // configure
    }
    return super.onCreateOptionsMenu(menu);
}
uuzelac
  • 156
  • 1
  • 5
  • both the onPrepareOptionsMenu and addOnPageChangeListener - is anyone better than the other or they are the same... – DragonFire Mar 29 '20 at 01:46
2

I answer my own question:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.menu_comunidad,
                              menu);

    return true;
}

// Called when invalidateOptionsMenu() is triggered
@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    if (mViewPager.getCurrentItem() == 4) {
        menu.findItem(R.id.action_search)
            .setVisible(true);
    } else {
        menu.findItem(R.id.action_search)
            .setVisible(false);
    }
    return super.onPrepareOptionsMenu(menu);
}

public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        // Respond to the action bar's Up/Home button
        case android.R.id.home:
            this.finish();
            return true;

        case R.id.action_search:

            return true;

        default:
            return super.onOptionsItemSelected(item);
    }
}
DragonFire
  • 3,722
  • 2
  • 38
  • 51
Elena
  • 181
  • 2
  • 12
1

OK..you will have to play with the ViewPager.OnPageChangeListener where you will monitor the method onPageSelected() that will be triggered whenever you change the page of the ViewPager. You will have to keep track of what is the current page AND dispatch a call to the ActivityCompat.invalidateOptionsMenu every time the onPageSelected() is called. This invalidateOptionsMenu() is the key to make it work, it will be responsible for triggering the 'refresh' of options menu..that will indirectly call the onCreateOptionsMenu() method will be called and you have the opportunity to 'hide' or 'show' a different set of items according to the selected tab.

For instance:

public boolean onCreateOptionsMenu(Menu menu) {
   ///

   if (currentPageIdx == 4) {
      // inflate menu for page 4
      // configure the menus
   } ....


  return super.onCreateOptionsMenu(menu);
}
Alécio Carvalho
  • 13,481
  • 5
  • 68
  • 74
  • I have updated my code with the onPageChangeListener, but how I create the menu inside this? Thanks – Elena Feb 05 '15 at 11:24
  • you have to create the onCreateOptionsMenu() method..the one that creates the menus...and on the onPageSelected() you just need to call: invalidateOptionsMenu(); the rest of the logic will go on the onCreateOptionsMenu() as written on my example. – Alécio Carvalho Feb 05 '15 at 13:53
0

Activity Menu

Set up your main menu excluding the menu items that are related to your fragments. ie.

<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        android:orderInCategory="300"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_help"
        android:title="@string/action_help"
        android:orderInCategory="400"
        app:showAsAction="never"
        android:visible="true"/>
</menu>

First Fragment Menu (mine is for assets)

<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <item
        android:id="@+id/action_add_asset"
        android:title="@string/add_new_asset"
        android:orderInCategory="100"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_edit_asset_type"
        android:title="@string/edit_asset_types"
        android:orderInCategory="200"
        app:showAsAction="never" />

</menu>

Second fragment menu (liabilities)

<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <item
        android:id="@+id/action_add_liability"
        android:title="@string/add_new_liability"
        android:orderInCategory="100"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_edit_liability_type"
        android:title="@string/edit_liability_types"
        android:orderInCategory="200"
        app:showAsAction="never" />
</menu>

Fragment Code (for both)

In your onActivityCreated in each fragment:

  setHasOptionsMenu(true);

Fragment 1 Code

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    super.onCreateOptionsMenu(menu, inflater)

    try {
        inflater.inflate(R.menu.menu_asset, menu)
    } catch (e: NullPointerException) {
        e.printStackTrace()
    }
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val id = item.itemId

    if (id == R.id.action_add_asset) {
        startNewActivity(NewAssetActivity::class.java)
        return true
    } else if (id == R.id.action_edit_asset_type) {
        startNewActivity(AssetTypeActivity::class.java)
        return true
    }
    return false
}

Fragment 2 code

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    super.onCreateOptionsMenu(menu, inflater)

    try {
        inflater.inflate(R.menu.menu_liability, menu)
    } catch (e: NullPointerException) {
        e.printStackTrace()
    }
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val id = item.itemId

    if (id == R.id.action_add_liability) {
        startNewActivity(NewLiabilityActivity::class.java)
        return true
    } else if (id == R.id.action_edit_liability_type) {
        startNewActivity(LiabilityTypeActivity::class.java)
        return true
    }
    return false
}

When you swipe between fragments using the view pager, the menus will change automatically.

Use the orderInCategory to show the correct order of the menus.

Nothing else is required, you dont need to hide/show anything.

SammyT
  • 759
  • 1
  • 9
  • 19