Vaibhav Sharma
Vaibhav Sharma

Reputation: 2319

Fragment - Getting view already has a parent error on calling onCreateView

I am inflating a fragment from activity at runtime. So, in order to inflate the view of the fragment in the fragment class I called:

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

At this moment I get a crash with logs:

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

But if I modify my method as:

      @Nullable
      @Override
      public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable final Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        return inflater.inflate(R.layout.confirm_fragment, null);
      }

where I now specify my container as null, it works. But what I didn't understand is where did I specify a parent for the view in the code which was crashing?

Upvotes: 1

Views: 558

Answers (4)

Pawneshwer Gupta
Pawneshwer Gupta

Reputation: 2342

You need to set attachToParent to false
Example:

inflater.inflate(R.layout.confirm_fragment, container,false);

Upvotes: 0

Bö macht Blau
Bö macht Blau

Reputation: 13009

where did I specify a parent for the view [...] ?

You add a Fragment dynamically by writing something like this:

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(android.R.id.content, myFragment, FRAGMENT_TAG)
                    .addToBackStack(null)
                    .commit();

In add(), you specify where the Fragment should be displayed (in this case fullscreen) by passing the id of the desired container.

See also the method description in the reference developers.android.com:

containerViewId int: Optional identifier of the container this fragment is to be placed in. If 0, it will not be placed in a container.

I you don't add a Fragment to the UI (e.g. you need it for caching purposes as a retained fragment), onCreateView() will never be called.

So once onCreateView() is called, the parent for this Fragment already exists - the FragmentManager set it for you.

Upvotes: 1

NightFury
NightFury

Reputation: 13546

Read from this link that why and when you pass parent container's instance or null in attachToRoot param.

From link:

Button button = (Button) inflater.inflate(R.layout.custom_button, mLinearLayout, false);
mLinearLayout.addView(button);

By passing in false, we say that we do not want to attach our View to the root ViewGroup just yet. We are saying that it will happen at some other point in time. In this example, the other point in time is simply the addView() method used immediately below inflation.

So if you inflate with:

return inflater.inflate(R.layout.confirm_fragment, container);

First it will immediately attach confirm_fragment to container. After returning the view, fragment will be tried to be added to parent again implicitly, but since it has been added already, exception will be thrown:

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

Hope you got the point.

Upvotes: 1

Joyal  C  Joseph
Joyal C Joseph

Reputation: 288

Try to use the following code:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view=inflater.inflate(R.layout.confirm_fragment, container, false);
    return view;
}

Upvotes: 0

Related Questions