54

I am doing a little exercise about a application you that put your name, and it returns "hello (the name you put)". But after i push the button i get the error "The specified child already has a parent. You must call removeView() on the child's parent first"

MainActivity.java

package com.example.holaamigos;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity {
    public final static String EXTRA_SALUDO = "com.example.holaamigos.SALUDO";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        final EditText txtNombre = (EditText)findViewById(R.id.TxtNombre);
        final Button btnHola = (Button)findViewById(R.id.BtnHola);
            
            btnHola.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(MainActivity.this, ActivitySaludo.class);
                    String saludo = txtNombre.getText().toString();
                    intent.putExtra(EXTRA_SALUDO, saludo);
                    startActivity(intent);
        }
                
    });
            
    }
                    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

ActivitySaludo.java

package com.example.holaamigos;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class ActivitySaludo extends Activity {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_saludo);
        
        Intent intent = getIntent();
        String saludo = intent.getStringExtra(MainActivity.EXTRA_SALUDO);
        
        //TextView txt = new TextView(this);
        //txt.setText(20);
        //txt.setText(saludo);
        
        TextView txtCambiado = (TextView) findViewById(R.id.TxtSaludo);
        txtCambiado.setText(saludo);
        setContentView(txtCambiado);
    }

}

activity_saludo.xml

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

</LinearLayout>

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/LblNombre"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/nombre" />
    
    <EditText
        android:id="@+id/TxtNombre"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text" />
    
    <Button 
        android:id="@+id/BtnHola"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hola_apy"
        android:onClick="enviarSaludo"/>

</LinearLayout>

LogCat

10-10 16:12:18.470: D/AndroidRuntime(810): Shutting down VM
10-10 16:12:18.470: W/dalvikvm(810): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
10-10 16:12:18.586: E/AndroidRuntime(810): FATAL EXCEPTION: main
10-10 16:12:18.586: E/AndroidRuntime(810): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.holaamigos/com.example.holaamigos.ActivitySaludo}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.app.ActivityThread.access$600(ActivityThread.java:141)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.os.Handler.dispatchMessage(Handler.java:99)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.os.Looper.loop(Looper.java:137)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.app.ActivityThread.main(ActivityThread.java:5041)
10-10 16:12:18.586: E/AndroidRuntime(810):  at java.lang.reflect.Method.invokeNative(Native Method)
10-10 16:12:18.586: E/AndroidRuntime(810):  at java.lang.reflect.Method.invoke(Method.java:511)
10-10 16:12:18.586: E/AndroidRuntime(810):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-10 16:12:18.586: E/AndroidRuntime(810):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-10 16:12:18.586: E/AndroidRuntime(810):  at dalvik.system.NativeStart.main(Native Method)
10-10 16:12:18.586: E/AndroidRuntime(810): Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.view.ViewGroup.addViewInner(ViewGroup.java:3339)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.view.ViewGroup.addView(ViewGroup.java:3210)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.view.ViewGroup.addView(ViewGroup.java:3186)
10-10 16:12:18.586: E/AndroidRuntime(810):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:289)
10-10 16:12:18.586: E/AndroidRuntime(810):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:279)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.app.Activity.setContentView(Activity.java:1901)
10-10 16:12:18.586: E/AndroidRuntime(810):  at com.example.holaamigos.ActivitySaludo.onCreate(ActivitySaludo.java:25)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.app.Activity.performCreate(Activity.java:5104)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
10-10 16:12:18.586: E/AndroidRuntime(810):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
10-10 16:12:18.586: E/AndroidRuntime(810):  ... 11 more
10-10 16:12:18.856: D/dalvikvm(810): GC_CONCURRENT freed 134K, 10% free 2630K/2908K, paused 73ms+83ms, total 237ms
Allan Veloso
  • 5,823
  • 1
  • 38
  • 36
Javier Coronel
  • 549
  • 1
  • 4
  • 3

13 Answers13

131

I encountered this error whenever I omitted a parameter while inflating the view for a fragment in the onCreateView() method like so:

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

The solution is to change the view inflation line to:

View view=inflater.inflate(R.layout.fragment_reject, container,false);

The explanation can be found at the Android guide for fragments

Quoting from the guide, the final parameter in the view initialization statement is false because:

"the system is already inserting the inflated layout into the container—passing true would create a redundant view group in the final layout"

Chad Bingham
  • 32,650
  • 19
  • 86
  • 115
Price
  • 2,683
  • 3
  • 17
  • 43
28

In onCreate with activity or onCreateView with fragment

 if (view != null) {
    ViewGroup parent = (ViewGroup) view.getParent();
    if (parent != null) {
        parent.removeView(view);
    }
}
try {
    view = inflater.inflate(R.layout.fragment_main, container, false);
} catch (InflateException e) {
    e.printStackTrace();
}
Cabezas
  • 9,329
  • 7
  • 67
  • 69
  • 1
    You are not far off, indeed reinflating an existing View causes that crash. You are correct. HOWEVER, according to this: http://android-developers.blogspot.co.uk/2009/01/avoiding-memory-leaks.html , you should not keep a reference to a view in the first place!!! So just inflate every time and delete the view member ! – Radu Jul 03 '14 at 16:27
  • the first part of the fix seems to work quite well, was searching for a solution for some time (not using layouts in my case) – andreimarinescu Aug 20 '14 at 10:38
  • this is great if you want to keep a view alive for the life of the app and keep adding it and removing from layouts - i.e. for when you have a view that takes a while to initialize. – Someone Somewhere Oct 27 '14 at 23:04
20

in ActivitySaludo, this line,

    setContentView(txtCambiado);

you must set the content view for the activity only once.

Jeffrey Blattman
  • 22,176
  • 9
  • 79
  • 134
10

You dont need this line: setContentView(txtCambiado);

duggu
  • 37,851
  • 12
  • 116
  • 113
Danilo Silva
  • 612
  • 2
  • 7
  • 16
5

In my case I was accidentally returning a child view from within Layout.onCreateView() as shown below:

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

    Button button = view.findViewById(R.id.some_button);

    return button; // <-- Problem is this
}

The solution was to return the parent view instead of the child view.

Sam
  • 40,644
  • 36
  • 176
  • 219
  • I was using databinding and did not realize I was not returning the root view. This answer helped me so much! – Lifes Aug 27 '23 at 16:32
2

In my case the problem was I was trying to add same view multiple times to linear layout

View childView = LayoutInflater.from(context).inflate(R.layout.lay_progressheader, parentLayout,false);

 for (int i = 1; i <= totalCount; i++) {

     parentLayout.addView(childView);

 }

just initialize view every time to fix the issue

 for (int i = 1; i <= totalCount; i++) {

     View childView = LayoutInflater.from(context).inflate(R.layout.lay_progressheader, parentLayout,false);

      parentLayout.addView(childView);

 }
Manohar
  • 22,116
  • 9
  • 108
  • 144
1

Try this way,hope this will help you to solve your problem.

TextView textView = new TextView(this);
textView.setText("CustomTextView");
addContentView(textView,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
Haresh Chhelana
  • 24,720
  • 5
  • 57
  • 67
1

if you are adding the same view repeatedly in a for loop .. if this is the case then try creating the View object of the layout inside the for loop . and add the view in side the for loop

To avoid such issues

Peter
  • 1,069
  • 2
  • 13
  • 24
  • Could you please elaborate more on this ? – AndroidGuy Apr 10 '17 at 11:01
  • 2
    for(int i = 0 ; i < x ; i++){ View v = create / inflate the view ll.addView(v); // every time the loop is created we need to create a new view which has to be added/ inflated to a empty linear layout . if you try to create the View outside the loop then and add that same view repetedly to the linear layout then an exceptionwill be raised asking you to remove the child from parent before adding a new one } ** if this is the issue then the answer is this . i dnt know if its a way around if their any other official better solution , this is what i do Hope it helps you – Peter Apr 11 '17 at 07:04
  • Thanks for this answer, it fixed the error in my app. – Sandeep Yohans Feb 27 '18 at 08:14
1

I’ve found a solution. I had to clear fragment’s parent from views before destroying and I’ve used the next peace of code for this:

in Java

public void onDestroyView() {
        if (rootView != null){
            ViewGroup viewGroup = (ViewGroup)rootView.getParent();
            if (viewGroup != null){
                viewGroup.removeAllViews();
            }
        }
        super.onDestroyView();
    }

in Kotlin

override fun onDestroyView() {
    if (rootView != null) {
        val viewGroup = rootView.parent as ViewGroup?
        viewGroup?.removeAllViews();
    }
    super.onDestroyView()
}
Fakhriddin Abdullaev
  • 4,169
  • 2
  • 35
  • 37
1

In my case i just pass the wrong view to the Method

Mohamed Ben Romdhane
  • 1,005
  • 3
  • 11
  • 22
0

You just need to initialize your view in onCreate() method and then in onCreateDialog() again before setView() and it should be work!

Spinner
  • 29
  • 4
0

I encountered this error while there is an invisible view in an activity xml layout. At that time it was not used in my case so I have removed it and the crash is not seen anymore.

0

frameLayout.addView(yourView); <----- if you are getting error on this line remove view from it's parent first

if (yourView.getParent() != null)

((ViewGroup) yourView.getParent()).removeView(yourView); frameLayout.addView(yourView); (Add view to layout)