java.lang.IllegalStateException: el hijo especificado ya tiene un padre


99

Estoy usando fragmentos, cuando instancia un fragmento la primera vez. pero la segunda vez obtuve esta excepción. ¿No pude encontrar la línea donde obtuve el error?

 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)

Esto es lo que hago cuando hago clic en un elemento de mi fragmento de lista.

// 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 primera vez que está bien, hago clic en element2 de la lista, también está bien; pero cuando vuelvo a element1 tengo este error.

¡Gracias a todos!


necesita llamar a layoutView.removeAllViews (); antes de agregar vistas al diseño
ρяσѕρєя K

@imrankhan mal! Puede agregar sin eliminar todo. Falta la parte más importante y como no hay un paquete personalizado en el stacktrace, le sugiero que elimine algún código y lo pruebe paso a paso ...
WarrenFaith

1
agrego más detalles, ¿puedes ver eso?
haythem souissi

¿Qué es esta clase RouteSearchFragment? No puedo encontrar ninguna referencia en los documentos de Android. Actualice también la definición de clase.
Noob

Respuestas:


36

Cuando anula OnCreateViewen su RouteSearchFragmentclase, tiene el

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

segmento de código?

Si es así, eliminar la declaración de devolución debería resolver su problema.

Puede conservar el código y devolver la vista si no desea volver a generar los datos de la vista, y el método onDestroyView () elimina esta vista de su padre así:

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

5
@Override public void onDestroyView () {super.onDestroyView (); ViewGroup parentViewGroup = (ViewGroup) mRoutesSearchViewContainer.getParent (); if (null! = parentViewGroup) {parentViewGroup.removeView (mRoutesSearchViewContainer); }}
haythem souissi

@Medo: ¿Puedes dar una breve explicación para esto? Tengo el mismo error que se muestra en logcat. como ha dado la sugerencia "eliminar la declaración de retorno debería resolver su problema", pero necesitamos devolver el objeto View en el método onCreateView (). ¿Puede proporcionar un fragmento de código para su explicación? Gracias.
Krishna Prasad

@Krishna Simplemente infle y devuelva la vista como lo haría normalmente. Puede omitir la declaración if completa.
Medo

65
Para mí, solo tuve que reemplazarlo return inflater.inflate(R.layout.fragment_search, container);conreturn inflater.inflate(R.layout.fragment_search, container, false);
Sufian

370

Lamento publicar una pregunta anterior, pero pude solucionarlo con una solución totalmente diferente. Recibí esta excepción, pero cambié la primera línea de mi anulación onCreatView de esto:

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

...a esto:

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

No tengo idea de por qué, pero el uso de la anulación que acepta el booleano como tercer parámetro lo solucionó. Creo que le dice al Fragmento y / o Actividad que no use el "contenedor" como padre de la Vista recién creada.


53
No se arrepienta, esto fue muy útil para mí y, claramente, para otras personas. ¡Gracias!
entrar en los códigos

Muchas gracias, sigo olvidando esto y volviendo a esta respuesta
noloman

@Patrick, el primero adjunta la vista inflada al contenedor, agregando la bandera falsa especifica que no desea agregar la vista inflada al contenedor.
Ne0

y sigo volviendo a esta publicación y descubriendo que esta es LA RESPUESTA :)
noloman

45

Me he enfrentado a este problema muchas veces. Agregue el siguiente código para resolver este problema:

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

Gracias


Gracias por esta solución :) Tengo un caso muy específico en el que no puedo usar el inflador para resolver esto. Me ahorraste mucho tiempo
Bojan

Lo siento, no entiendo del todo porque soy nuevo en Android.
Zin Win Htet

In view.getParent (); ¿De dónde viene el objeto de vista de dosis?
Zin Win Htet

Cristy YG: Tome una instancia de View como variable global e infle su diseño xml en la variable global anterior. me estas siguiendo o no?
Hardik

Sí, ver la instancia declarar como global.
Hardik

35

Si tiene esta declaración ...

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

Entonces intente esto .. Agregue falso como tercer argumento .. Puede ser que pueda ayudar ..

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

21

Tenía este código en un fragmento y fallaba si intento volver a este fragmento

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

después de recopilar las respuestas en este hilo, me di cuenta de que el padre de mRootView todavía tiene mRootView como hijo. Entonces, esta fue mi solución.

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

espero que esto ayude


2
+1 me ayudó. Especialmente cierto si su actividad se mantiene, pero el administrador de fragmentos agrega nuevos fragmentos en la parte superior. cuando vuelva al primer fragmento, debe asegurarse de que se elimine la vista raíz anterior. ¡Gracias!
Bundeeteddee

Me ayudó mucho. He estado encontrando esa solución durante 3 días. Respuesta simple y bonita.
Zin Win Htet

¡Guauu! finalmente funcionó para mí! gran solución. ¡Gracias!
avisper

No tengo una razón fundamental por la que "(ViewGroup) mRootView.getParent ()). RemoveView (mRootView);" funciona en contraste con llamar directamente "<WhateverIsParentViewGroupName> .removeView (mRootView)" Pero esto también funciona para mí, estoy probando en Android 8.0 y 9.0. Gracias bud ^
Khay

16

También sucede cuando la vista devuelta por onCreateView () no es la vista que se infló.

Ejemplo:

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;

Reparar:

return rootView;

En vez de:

return textView; // or whatever you returned

¡Gracias! ¡Me ayudó!
Sudheesh Mohan

5

Tuve este problema y no pude resolverlo en código Java. El problema fue con mi xml.

Estaba intentando agregar un textView a un contenedor, pero había envuelto el textView dentro de un LinearLayout.

Este era el archivo xml original:

<?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>

Ahora con el LinearLayout eliminado:

<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"/>

Esto no me pareció mucho, pero funcionó y no cambié mi código Java en absoluto. Todo estaba en xml.


2

Está agregando a Viewen a layout, pero la Vista ya está en otra layout. Una vista no puede estar en más de un lugar.


Agregué más detalles a mi pregunta, ¿pueden ver eso?
haythem souissi

1

Esta solución puede ayudar:

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
Creo que rootView siempre será nulo ya que no lo inicializó.
Zin Win Htet

rootView siempre será nulo
Thinsky

1

Lo resolví configurando attachToRoot de inflater.inflate()a false.

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

0

en su archivo xml debe establecer layout_width y layout_height de wrap_content a match_parent. está arreglado para mí.

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.