web-dev-qa-db-fra.com

java.lang.IllegalStateException: l'enfant spécifié a déjà un parent

J'utilise des fragments, quand j'instancie un fragment la première fois. mais la deuxième fois, j'ai eu cette exception. Je ne pouvais pas trouver la ligne où j'ai eu l'erreur?

 04-04 08:51:54.320: E/AndroidRuntime(29713): FATAL EXCEPTION: main
    04-04 08:51:54.320: E/AndroidRuntime(29713): Java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.view.ViewGroup.addViewInner(ViewGroup.Java:3013)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.view.ViewGroup.addView(ViewGroup.Java:2902)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.view.ViewGroup.addView(ViewGroup.Java:2859)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.view.ViewGroup.addView(ViewGroup.Java:2839)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.support.v4.app.NoSaveStateFrameLayout.wrap(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.support.v4.app.BackStackRecord.run(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.support.v4.app.FragmentManagerImpl.execPendingActions(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.support.v4.app.FragmentManagerImpl$1.run(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.os.Handler.handleCallback(Handler.Java:587)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.os.Handler.dispatchMessage(Handler.Java:92)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.os.Looper.loop(Looper.Java:132)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Android.app.ActivityThread.main(ActivityThread.Java:4126)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Java.lang.reflect.Method.invokeNative(Native Method)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at Java.lang.reflect.Method.invoke(Method.Java:491)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:844)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:602)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at dalvik.system.NativeStart.main(Native Method)

Voici ce que je fais quand je clique sur un élément de ma liste fragment.

// If we are not currently showing a fragment for the new
 // position, we need to create and install a new one.
 RouteSearchFragment df = RouteSearchFragment.newInstance(index);

 // Execute a transaction, replacing any existing fragment
 // with this one inside the frame.
 FragmentTransaction ft = fragmentManager.beginTransaction();
 ft.replace(R.id.details_full, df);
 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
 ft.commit();

La première fois que c'est ok, je clique sur element2 de la liste, c'est aussi ok; mais quand je reviens à element1 j'ai eu ce bogue.

Merci tout le monde!

88
haythem souissi

Lorsque vous remplacez OnCreateView dans votre classe RouteSearchFragment, avez-vous le 

if(view != null) {
    return view; 
}

segment de code?

Si tel est le cas, la suppression de l'instruction de retour devrait résoudre votre problème.

Vous pouvez conserver le code et renvoyer la vue si vous ne souhaitez pas régénérer les données de la vue. La méthode onDestroyView () vous permet de supprimer cette vue de son parent comme suit:

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (view != null) {
            ViewGroup parent = (ViewGroup) view.getParent();
            if (parent != null) {
                parent.removeAllViews();
            }
        }
    }
28
Medo

Désolé de poster une vieille question, mais j’ai pu résoudre le problème en utilisant une solution totalement différente. J'obtenais cette exception mais j'ai changé la première ligne de mon remplacement onCreatView à partir de ceci:

View result = inflater.inflate(R.layout.customer_layout, container);

...pour ça:

View result = inflater.inflate(R.layout.customer_layout, container, false);

Je ne sais pas pourquoi mais utiliser le remplacement qui accepte le booléen comme troisième paramètre le corrige. Je pense que cela indique au fragment et/ou à l'activité de ne pas utiliser le "conteneur" comme parent de la vue nouvellement créée. HTH!

364
Patrick

J'ai souvent eu à faire face à ce problème . Veuillez ajouter le code suivant pour résoudre ce problème:

@Override
    public void onDestroyView() {
        super.onDestroyView();
        if (view != null) {
            ViewGroup parentViewGroup = (ViewGroup) view.getParent();
            if (parentViewGroup != null) {
                parentViewGroup.removeAllViews();
            }
        }
    }

Merci

43
Hardik

Si vous avez cette déclaration ..

View view = inflater.inflate(R.layout.fragment1, container);//may be Incorrect 

Alors essayez ceci .. Ajoutez false comme troisième argument .. Peut-être que cela pourrait aider ..

View view = inflater.inflate(R.layout.fragment1, container, false);//correct one
34
Dhananjay M

J'ai eu ce code dans un fragment et il s'est écrasé si j'essaie de revenir à ce fragment

if (mRootView == null) {
    mRootView = inflater.inflate(R.layout.fragment_main, container, false);
} 

après avoir rassemblé les réponses sur ce fil de discussion, je me suis rendu compte que le parent de mRootView avait toujours mRootView comme enfant. Donc, c'était ma solution.

if (mRootView == null) {
    mRootView = inflater.inflate(R.layout.fragment_main, container, false);
} else {
    ((ViewGroup) mRootView.getParent()).removeView(mRootView);
}

j'espère que cela t'aides

21
user1736525

Cela se produit également lorsque la vue renvoyée par onCreateView () n'est pas la vue gonflée.

Exemple:

View rootView = inflater.inflate(R.layout.my_fragment, container, false);

TextView textView = (TextView) rootView.findViewById(R.id.text_view);
textView.setText("Some text.");

return textView;

Réparer:

return rootView;

Au lieu de:

return textView; // or whatever you returned
15
Mateus Pires

J'ai eu ce problème et je ne pouvais pas le résoudre en code Java. Le problème était avec mon xml.

J'essayais d'ajouter un textView à un conteneur, mais j'avais enveloppé le textView à l'intérieur d'un LinearLayout.

C'était le fichier XML d'origine:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">
    
    <TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:id="@Android:id/text1"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:textAppearance="?android:attr/textAppearanceListItemSmall"
        Android:gravity="center_vertical"
        Android:paddingLeft="16dp"
        Android:paddingRight="16dp"
        Android:textColor="#fff"
        Android:background="?android:attr/activatedBackgroundIndicator"
        Android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

</LinearLayout>

Maintenant, avec LinearLayout enlevé:

<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:id="@Android:id/text1"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:textAppearance="?android:attr/textAppearanceListItemSmall"
        Android:gravity="center_vertical"
        Android:paddingLeft="16dp"
        Android:paddingRight="16dp"
        Android:textColor="#fff"
        Android:background="?android:attr/activatedBackgroundIndicator"
        Android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

Cela ne m'a pas semblé beaucoup, mais cela a fonctionné, et je n'ai pas du tout changé de code Java. Tout était dans le XML.

5
DroidCrafter

Vous ajoutez une View à une layout, mais la vue se trouve déjà dans une autre layout. Une vue ne peut pas être dans plus d'un endroit.

2
noob

Cette solution peut aider:

public class FragmentItem extends Android.Support.V4.App.Fragment
{
    View rootView;
    TextView textView;

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (rootView != null) 
        {
            ViewGroup parent = (ViewGroup)rootView.Parent;
            parent.RemoveView(rootView);
        } else {
            rootView = inflater.Inflate(Resource.Layout.FragmentItem, container, false);
            textView = rootView.FindViewById<TextView>(Resource.Id.textViewDisplay);            
        }
        return rootView;
    }
}
1
Bhavit S. Sengar

Je l'ai résolu en définissant attachToRoot of inflater.inflate() à false.

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

dans votre fichier XML, vous devez définir layout_width et layout_height de wrap_content à match_parent. c'est fixé pour moi.

<FrameLayout
        Android:id="@+id/container"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />
0
Evan Ngo