MapFragment in Action Bar Tabs

In the following solution, it is possible to add a GoogleMap to an Action Bar tab/dropdown. The key to doing this lies in correctly setting up your fragment to destroy the MapFragment when switching to another fragment in the Action Bar.

Create an Activity that implements the Action Bar functionality:

  1. Create a project in Eclipse that uses Tabs for the main activity. If you don't do this, proceed to steps 2-5.
  2. Create a class that extends Activity and implements ActionBar.OnNavigationListener.
  3. Create a layout XML file that is a container for your tab fragments when you switch between them.
  4. Implement/override the following method in your Activity class: public boolean onNavigationItemSelected(int position, long id).
  5. In this method, switch between the position object to determine the selected tab and set the fragment to a new instance using the FragmentManager like this: getFragmentManager().beginTransaction().replace(R.id.container, fragment).commit().

Create a fragment that holds the map:

  1. Create a class that extends Fragment to use as your tab's fragment. Read [1] to better understand the MapFragment.
  2. Create a layout XML file that contains a fragment element (as seen in [1]).Use the XML in that page to create a layout XML file and use it in your fragment class.
  3. Inflate that layout XML file in your fragment class by overriding onCreateView.
  4. Your app should now display a map in the tab that uses your fragment class, however, switching to another tab and back to the map tab will result in a duplicate view ID. To overcome this, go on to the next step.
  5. In your fragment class, override the following method to specifically destroy the underlying GoogleMap object so that it can be recreated when the map tab loads your fragment class again:

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        MapFragment f = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        if (f != null) 
            getFragmentManager().beginTransaction().remove(f).commit();
    }