MapFragment in Fragment, alternatives?

As described here

To display MapFragment inside the fragment(NestedFragment): At this point I believe you have

  1. added necessary permission on manifest
  2. added google play service as a lib project
  3. api key in manifest file. 4.

where.xml

 <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:map="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical" >
         <FrameLayout
           android:layout_width="match_parent"
           android:layout_height="0dp"
           android:layout_weight="1.03"
           android:name="com.google.android.gms.maps.SupportMapFragment"
           android:id="@+id/mapwhere" />


          <TextView
           android:layout_width="match_parent"
           android:layout_height="wrap_content"/>

        </LinearLayout>

class:

 public class WhereFragment extends SupportMapFragment {

    @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
     {
      super.onCreateView(inflater, container, savedInstanceState);
      View root = inflater.inflate(R.layout.where, null, false); 
      initilizeMap();
      return root;
     }

    private void initilizeMap()
     {
      mSupportMapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapwhere);
      if (mSupportMapFragment == null) {
       FragmentManager fragmentManager = getFragmentManager();
       FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
       mSupportMapFragment = SupportMapFragment.newInstance();
       fragmentTransaction.replace(R.id.mapwhere, mSupportMapFragment).commit();
         }
      if (mSupportMapFragment != null)
      {
       googleMap = mSupportMapFragment.getMap();
       if (googleMap != null)
        googleMap.setOnMapClickListener(new OnMapClickListener()
        {
         @Override
         public void onMapClick(LatLng point)
         {
          //TODO: your onclick stuffs
         }
        });
      }
     }
    }

Documentation:

Nested Fragments You can now embed fragments inside fragments. This is useful for a variety of situations in which you want to place dynamic and re-usable UI components into a UI component that is itself dynamic and re-usable. For example, if you use ViewPager to create fragments that swipe left and right and consume a majority of the screen space, you can now insert fragments into each fragment page.

To nest a fragment, simply call getChildFragmentManager() on the Fragment in which you want to add a fragment. This returns a FragmentManager that you can use like you normally do from the top-level activity to create fragment transactions. For example, here’s some code that adds a fragment from within an existing Fragment class:

Fragment videoFragment = new VideoPlayerFragment(); FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); transaction.add(R.id.video_fragment, videoFragment).commit(); From within a nested fragment, you can get a reference to the parent fragment by calling getParentFragment().

The Android Support Library also now supports nested fragments, so you can implement nested fragment designs on Android 1.6 and higher.

Note: You cannot inflate a layout into a fragment when that layout includes a . Nested fragments are only supported when added to a fragment dynamically.

source:http://developer.android.com/about/versions/android-4.2.html#NestedFragments

This will also fix for:

 11-06 11:36:01.509: E/AndroidRuntime(6309): FATAL EXCEPTION: main
    11-06 11:36:01.509: E/AndroidRuntime(6309): android.view.InflateException: Binary XML file line #9: Error inflating class fragment
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:710)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:752)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:760)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:760)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:760)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:760)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.view.LayoutInflater.inflate(LayoutInflater.java:495)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at com.abc.android.ui.WhereFragment.onCreateView(WhereFragment.java:60)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
    11-06 11:36:01.509: E/AndroidRuntime(6309):  at a ...

Use SupportMapFragment to overcome this error:

In fragment layout

<fragment
android:id="@+id/googleMap"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />

In Your Fragment onCreateView

SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.googleMap);

        if (mapFragment != null) {
            mapFragment.getMapAsync(this);
        }

Since your layout is in the Fragment's layout, therefore the SupportMapFragment is the child layout of your fragment. Hence use getChildFragmentManager() which is Fragment's FragmentManager


Use MapView instead of MapFragment in your Fragment's layout. Remember to call MapView's lifecycle methods:

  • onCreate(Bundle)
  • onResume()
  • onPause()
  • onDestroy()
  • onSaveInstanceState(Bundle)
  • onLowMemory()

as described here.

Btw. you shouldn't be using MapFragment, only SupportMapFragment and support library.

Edit:

If you switch to support library, you can use code from comment #1 here: http://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1