Search code examples
androidandroid-layoutandroid-fragmentsandroid-fragmentactivityandroid-dialogfragment

Programmatically add Fragment to inner ViewGroup


I'm attempting to add a two Fragments to the following layout:

dialog_empty_linear_layout.xml:

    <LinearLayout
        android:id="@+id/ParentLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

Using the following code:

setContentView(R.layout.dialog_empty_linear_layout);

int parentViewId = getIntent().getIntExtra(PARENT_VIEW_ID, -1); // == R.id.ParentLayout
if (parentViewId == -1)
    parentViewId = android.R.id.content;

/*
 * Extracting Fragments types
 */
Class<? extends Fragment>[] fragmentTypes = getFragments(); // there are two fragments here!

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
for (Class<? extends Fragment> fragmentType  : fragmentTypes) {
    Fragment fragment = Tools.createNewInstance(fragmentType);
    ft.add(parentViewId, fragment);
}
ft.commitAllowingStateLoss();

While executing the code I receive the following error:

Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

I was quite surprised because this is a newly created Activity, with a newly created fragments and newly created views...

So I've followed the stack trace and checked which child and which parent are we talking about since the exception did not gave any extra info about it...

I was more surprised to find out the Child is the LinearLayout(e.g. R.ParentLayout), and the Parent was the RelativeLayout wrapping it.

Perhaps once again I miss the obvious but I thought that:

ft.add(parentViewId, fragment);

Suppose to add the Fragment to the parentViewId layout, and not to attempt to add the parentViewId layout to its parent layout...

ALSO, if I use the following XML everything works fine:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ParentLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

</LinearLayout>

Any insights?


Solution

  • Well, That was interesting... and for those of you that encounter this... pay good attention this is extremely stupid!

    Overriding this method in the Fragment:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_id, container);
    }
    

    And here is the stupid thing...

    The inflater.inflate has another overloading:

        return inflater.inflate(R.layout.fragment_id, container, **addToRoot**);
    

    For some reason I expected the fragment layout to be added to the container(Don't trust intuition), and not to add the container to the rootView. Until today, I've been adding all my Fragments to my root view, (container == rootView) so this problem didn't occur, but once the container is not the rootView, I MUST explicitly state addToRoot=false, e.g.

        return inflater.inflate(R.layout.fragment_id, container, false);
    

    Well, that is that guys... stupidity by a boolean!