Note: The following solution apply to adding any fragment (not just SupportMapFragment
) in a fragment.
Nested Fragments
If you use SupportMapFragment
in a fragment, you might bump into the following error.
android.view.InflateException: Binary XML file line #16: Binary XML file line #16: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #16: Error inflating class fragment
Caused by: java.lang.IllegalArgumentException: Binary XML file line #16: Duplicate id 0x7f0d008a, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.SupportMapFragment
Based on Android Nested Fragments documentation.
You cannot inflate a layout into a fragment when that layout includes a
<fragment>
. Nested fragments are only supported when added to a fragment dynamically.
Edit layout file
Edit your fragment's layout file to remove <fragment>
and add a Layout as fragment placeholder.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
...>
<!-- Remove existing fragment
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
-->
<!-- replace with a Layout as Fragment placeholder -->
<FrameLayout
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.constraint.ConstraintLayout>
Add code
Replace getSupportFragmentManager()
used in a Activity to getChildFragmentManager()
used in a Fragment.
Remove findFragmentById
code (previosly inflated by layout using <Fragment>
). Create SupportMapFragment
instance manually and replace R.id.map
layout with SupportMapFragment
instance by using FragmentTransaction
.
public static class PlaceholderFragment extends Fragment { private SupportMapFragment mapFragment; ... @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_tab, container, false); // Remove old code // SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map); // don't recreate fragment everytime ensure last map location/state are maintained if (mapFragment == null) { mapFragment = SupportMapFragment.newInstance(); mapFragment.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap googleMap) { LatLng latLng = new LatLng(1.289545, 103.849972); googleMap.addMarker(new MarkerOptions().position(latLng) .title("Singapore")); googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng)); } }); } // R.id.map is a FrameLayout, not a Fragment getChildFragmentManager().beginTransaction().replace(R.id.map, mapFragment).commit(); return rootView; }}