1

I'm trying to show a DialogFragment with a SupportMapFragment inside.

When i'm loading the fragment as a regular fragment - it works great.

When i'm loading the fragment as a dialog using the show() function i receive the following error with stacktrace:

03-14 16:54:20.443: E/AndroidRuntime(20856): FATAL EXCEPTION: main
03-14 16:54:20.443: E/AndroidRuntime(20856): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.coapps.pico/com.coapps.pico.MainActivity}: android.view.InflateException: Binary XML file line #47: Error inflating class fragment
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.access$700(ActivityThread.java:140)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.os.Looper.loop(Looper.java:137)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.main(ActivityThread.java:4921)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at java.lang.reflect.Method.invokeNative(Native Method)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at java.lang.reflect.Method.invoke(Method.java:511)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at dalvik.system.NativeStart.main(Native Method)
03-14 16:54:20.443: E/AndroidRuntime(20856): Caused by: android.view.InflateException: Binary XML file line #47: Error inflating class fragment
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.coapps.pico.fragments.BasicFragment.onCreateDialog(BasicFragment.java:53)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:295)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1082)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:310)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.coapps.pico.fragments.BasicFragment.onCreateDialog(BasicFragment.java:53)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:295)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:570)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at com.coapps.pico.MainActivity.onStart(MainActivity.java:86)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1178)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.Activity.performStart(Activity.java:5216)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2083)
03-14 16:54:20.443: E/AndroidRuntime(20856):    ... 11 more
03-14 16:54:20.443: E/AndroidRuntime(20856): Caused by: java.lang.IllegalArgumentException: Binary XML file line #47: Duplicate id 0x7f05008c, tag null, or parent id 0x0 with another fragment for com.google.android.gms.maps.SupportMapFragment
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:296)
03-14 16:54:20.443: E/AndroidRuntime(20856):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
03-14 16:54:20.443: E/AndroidRuntime(20856):    ... 36 more

this is my fragment layout:

<?xml version="1.0" encoding="utf-8"?>
<!-- dialog layout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:background="@drawable/background_white"
    android:orientation="vertical"
    android:paddingBottom="15dp"
    android:paddingTop="15dp"
    android:paddingLeft="20dp"
    android:paddingRight="20dp" >

    <!-- dialog caption -->

    <TextView
        android:id="@+id/fragment_create_public_event_caption_textview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:hint="@string/hint_event_name"
        android:text="@string/create_quick_event"
        android:textColor="@color/text_grey"
        android:textSize="12sp" />

    <!-- event name -->

    <EditText
        android:id="@+id/fragment_create_public_event_event_name_edittext"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:background="@drawable/edittext_background"
        android:drawableLeft="@drawable/icon_name"
        android:drawablePadding="10dp"
        android:hint="@string/hint_event_name"
        android:paddingBottom="5dp"
        android:paddingLeft="10dp"
        android:paddingTop="5dp"
        android:textAppearance="@android:style/TextAppearance.Small"
        android:textColorHint="@color/text_grey" />

    <!-- map -->

    <fragment
        android:id="@+id/fragment_create_public_event_map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="fill_parent"
        android:layout_height="100dp"
        android:layout_marginTop="5dp" />

    <!-- create button -->

    <TextView
        android:id="@+id/fragment_create_public_event_create_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:background="@drawable/button_orange"
        android:clickable="true"
        android:drawableLeft="@drawable/button_create_quick_event"
        android:drawablePadding="5dp"
        android:layout_gravity="center_horizontal"
        android:gravity="center"
        android:paddingBottom="5dp"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:paddingTop="5dp"
        android:text="@string/create_quick_event_button"
        android:textAppearance="@android:style/TextAppearance.Large"
        android:textColor="@android:color/white" />

</LinearLayout>

This is my MapFragment:

public class CreatePublicEventFragment extends BasicFragment{

    /**
     * Tag for creating the public event
     */
    public static final String CREATE_PUBLIC_EVENT_TAG = "createPublicEvent";

    /**
     * create a new instance of {@link CreatePublicEventFragment}
     */
    public static CreatePublicEventFragment newInstance()
    {
        Bundle args = new Bundle();
        CreatePublicEventFragment fragment = new CreatePublicEventFragment();       
        //put the type as dialog
        args.putInt(BasicFragment.KEY_TYPE, BasicFragment.DIALOG);
        fragment.setArguments(args);
        return fragment;        
    }   

    /**
     * The event's name {@link EditText}
     */
    private EditText name;

    /**
     * The create button {@link TextView}
     */
    private TextView createButton;

    /**
     * The google's map {@link GoogleMap}
     */
    private GoogleMap map;

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_create_public_event;
    }

    @Override
    protected void findViews(View view) {
        name = (EditText) view.findViewById(R.id.fragment_create_public_event_event_name_edittext);
        createButton = (TextView) view.findViewById(R.id.fragment_create_public_event_create_textview);
        //get the map
        SupportMapFragment mapFramgment = ((SupportMapFragment) getMainActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_create_public_event_map));
        map = mapFramgment.getMap();        
    }

    @Override
    protected void setViews() {
        centerTheMap();
    }

    /**
     * Center the map to user's position
     */
    private void centerTheMap()
    {
        LatLng position;
        Marker marker;
        //get the user
        PicoUser user = getMainActivity().getPicoUser();        
        LocationClient locationClient= getMainActivity().getPicoLocationManager().getLocationClient();
        if (locationClient == null || !locationClient.isConnected())
            return;
        //get the last known location
        user.setLocation(getMainActivity().getPicoLocationManager().getLocationClient().getLastLocation());
        //create a LatLng
        position = new LatLng(user.getLocation().getLatitude(), user.getLocation().getLongitude());     
        marker = map.addMarker(new MarkerOptions().position(position).title("You are here").icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_map_pin)));
        marker.showInfoWindow();
        map.animateCamera(CameraUpdateFactory.newLatLng(position));     
    }
}

This is my FragmentActivity onCreate():

    @Override
    protected void onCreate(Bundle savedInstanceState) {        
        super.onCreate(savedInstanceState);     
        setContentView(R.layout.main_activity);     
        if (!checkPlayServices())
            return;         
        //create application's managers
        createManagers();
        //showFragment(null, new CreatePublicEventFragment(), false, true);
        CreatePublicEventFragment.newInstance().show(getSupportFragmentManager(), CreatePublicEventFragment.CREATE_PUBLIC_EVENT_TAG);
}
Asaf Nevo
  • 11,338
  • 23
  • 79
  • 154

1 Answers1

0

The underlying issue is the same as the issue in this SO question, to which I answered similarly.

Although I don't see code for your ...BasicFragment.onCreateDialog method, I see your layout contains a <fragment.../> declaration for your SupportMapFragment. As you're putting this inside a DialogFragment, you're running afoul of one of the restrictions when using nested/child fragments:

As noted obscurely in the 4.2 API changes doc

You cannot inflate a layout into a fragment when that layout includes a <fragment>.
Nested fragments are only supported when added to a fragment programmatically.

Attempting said inflation under these conditions will cause the InflateException (Error inflating class fragment) you're seeing.

Instead, the layout for your DialogFragment should contain a <FrameLayout.../> for the SupportMapFragment - replacing the explicit <fragment.../> - with which you can add your SupportMapFragment programmatically and avoid the exception.


Note: Child/Nested fragments must be managed via a FragmentManager from getChildFragmentManager() (there is a version in the support library, as well), so you would want to change the existing call(s) to getSupportFragmentManager() in the CreatePublicEventFragment class (not the call from your FragmentActivity used to .show(...)) when setting up your FragmentTransaction for adding the map fragment programmatically.

In your case, you'd need to make sure the BasicFragment superclass won't try to use the wrong FragmentManager, then override any methods as necessary to use the correct API for handling nested/child fragments.

Community
  • 1
  • 1
Brian Webb
  • 111
  • 4