user1045680
user1045680

Reputation: 859

Add Action Button to Action Bar For One Fragment

My app has three tabs and I am using a pager to switch between the tabs. Each tab has its own fragment. I added the Settings and Help action buttons to the action bar in the main Activity using the OptionsMenu methods. I now want to add a new action button to the action bar, but just for the first tab and first fragment, and I don't want it to appear on the other fragments when they are displayed in their tabs.

I have this layout for the main menu that is created in the main activity -

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

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

This menu displays correctly and works as expected.

I have another menu, menu_prelaunch_fragment for the first fragment -

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

    <item android:id="@+id/clear_form"
        android:title="Clear"
        android:icon="@drawable/ic_action_action_delete"
        app:showAsAction="always" />
</menu>

and I add it to the action bar using the following code in the first fragment -

@Override
public void onCreate(Bundle savedInstance) {
    Log.d(TAG, "onCreate");
    super.onCreate(savedInstance);
    setHasOptionsMenu(true);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflator) {
    Log.d(TAG, "onCreateOptionsMenu");
    inflator.inflate(R.menu.menu_prelaunch_fragment, menu);
    super.onCreateOptionsMenu(menu, inflator);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Log.d(TAG, "onOptionsItemSelected");
    if (item.getItemId() == R.id.clear_form)
        clearFragmentData();
    return super.onOptionsItemSelected(item);
}

The problem is that this added button does not go away when I go to the other fragments on the other pages/tabs. The other fragments do not have any options menu code in them.

I then added this code to the other fragments to remove the one button.

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "onCreate");
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public void onPrepareOptionsMenu (Menu menu) {
    menu.findItem(R.id.clear_form).setVisible(false);
    super.onPrepareOptionsMenu(menu);
}

But now the clear button does not appear in the action bar regardless of what tabs are selected.

How do I add an action button to the action bar just for one tab (ie fragment) in my three tab (ie three fragment) app? It should only appear when that tab (fragment) is selected (displayed).

Thanks!

Upvotes: 3

Views: 6122

Answers (3)

Roshan
Roshan

Reputation: 3592

An easier approach would be to include the menu item in your activity menu items and programatically show and hide it based on tab selection. Get a reference to the menu item in onCreateOptionsMenu method and keep it available outside.

@Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu, menu);
          checkOut = (MenuItem) menu.findItem(R.id.action_abc);  
        return true;
    }

Use a addOnPageChangeListener on the viewpager to change the visibility of the menu item.

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

            }

            @Override
            public void onPageSelected(int position) {
                if (position == 0) {               
                    menuItem.setVisible(true);
                } else {
                    menuItem.setVisible(false);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

I have not tried this out myself.

Upvotes: 3

user1045680
user1045680

Reputation: 859

This is how I solved the problem of having an icon in the action bar for only one page in a view pager.

  1. Create the full menu, including the item that only should be displayed for a particular page, in the main activity the usual way. Save a reference to the menuItem that changes for each page in the Application object.

  2. Implement the onPageChangelistener as above, and set the visibility of the menuItem as needed for each page. You get access to the menuItem from the Application object. This keeps the menu items as you want them in a particular phone orientation, but will fail when the orientation of the phone changes. Save the current page position in the Application object. Be sure to initialize the page position in the Application object to the first page (ie 0).

  3. In the onCreateOptionsMenu in the main activity, use the current page position (found in the Application object) to determine if the menuItem should be visible or not. This will take care of screen rotations.

Upvotes: 1

TouchBoarder
TouchBoarder

Reputation: 6492

When you create a newInstance of you TabFragement in the tab page adapter include the tab section number in the Fragment arguments.

/**
 * Returns a new instance of this fragment for the given tab section
 * number.
 */
public static TabFragment newInstance(int sectionNumber) {
    TabFragment fragment = new TabFragment ();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    fragment.setArguments(args);
    return fragment;
}

then in the Fragment OnCreate check the tab section number to set if the fragment should have a option menu

only section number 0 inflates menu: setHasOptionsMenu(sectionNumber==0?true:false);

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    sectionNumber=getArguments().getInt(ARG_SECTION_NUMBER);

    setHasOptionsMenu(sectionNumber==0?true:false);
}

And inflate the Fragemnt menu in void onCreateOptionsMenu

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflator) {
    inflator.inflate(R.menu.first_tab_menu, menu);
    super.onCreateOptionsMenu(menu, inflator);
}

Upvotes: 0

Related Questions