2011-10-18 13 views
5

Estoy trabajando en 3.0 por primera vez. Quiero añadir fragmentos dinámicamente, pero su error que se muestra: -Obteniendo error al agregar fragmentos dinámicamente -java.lang.IllegalStateException:

10-18 18:29:11.215: ERROR/AndroidRuntime(3550): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 

código XML

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

<ListView 
     android:id="@+id/number_list" 
     android:layout_width="250dip" 
     android:layout_height="match_parent" /> 

<FrameLayout 
     android:id="@+id/the_frag" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

Actividad

public class FragmentExampleActivity extends Activity implements 
    OnItemClickListener { 
/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    ListView l = (ListView) findViewById(R.id.number_list); 
    ArrayAdapter<String> numbers = new ArrayAdapter<String>(
      getApplicationContext(), android.R.layout.simple_list_item_1, 
      new String[] { "one", "two", "three", "four", "five", "six" }); 
    l.setAdapter(numbers); 
    l.setOnItemClickListener(this); 
} 

public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 

    Fragment f = new FragmentExample(); 

    FragmentTransaction ft = getFragmentManager().beginTransaction();  
    ft.replace(R.id.the_frag, f); 
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    ft.addToBackStack(null); 
    ft.commit(); 

} 
} 


public class FragmentExample extends Fragment { 
private int nAndroids=1; 

public FragmentExample() { 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) { 
    int n; 

    View l = inflater.inflate(R.layout.textlay,container); 
    TextView tv = (TextView) l.findViewById(R.id.textView1); 
    tv.setText("value "+nAndroids); 

    return l; 
} 

}

PLZ poner un poco de luz sobre, dónde voy mal :(

Respuesta

19

En lugar de utilizar

View l = inflater.inflate(R.layout.textlay,container); 

se debe utilizar

View l = inflater.inflate(R.layout.textlay, container, false); 

o alternativamente

View l = inflater.inflate(R.layout.textlay, null); 

Sugiero que use la versión de inflate que toma tres parámetros. Android usa el contenedor solo para el propósito de los params del diseño. Pasando false como tercer parámetro, evita la adición de textlay, a container y corrige su problema

+0

Thankx funcionó :) – voidRy

+0

Pero y pasamos null? – voidRy

+2

El contenedor solo se debe usar para los Parámetros de diseño. No durante la inflación. – Spidy

3

o puede utilizar el tercer argumento y pasarlo como falso.

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

significa que no se conecta la vista actual a la raíz.

4

si en onCreateView(), desea volver a utilizar la vista, entonces se puede tratar con onDestroyView()

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

A continuación se soluciona varios problemas:

public static View contentView; 

public static class MenuCardFrontFragment extends Fragment { 
    public MenuCardFrontFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     try 
     { 
      LinearLayout frontLayout = (LinearLayout)inflater.inflate(R.layout.content_card, container, false); 
      // modify layout if necessary 
      return contentView = frontLayout; 
     } catch (InflateException e) { 
      return contentView; 
     } 
    } 

    @Override 
    public void onDestroyView() { 
     super.onDestroyView(); 
     if (contentView != null) { 
      ViewGroup parentViewGroup = (ViewGroup) contentView.getParent(); 
      if (parentViewGroup != null) { 
       parentViewGroup.removeAllViews(); 
      } 
     } 
    } 
} 
  1. Si fragmentos de espectáculos con animación y usuario forzado a repetir la animación antes de que termine. Ej .: presionar el botón de menú dos veces antes de que el fragmento de menú termine de animarse y aparezca. (Esto fue resuelto por el onDestryView desde el usuario2764384)

  2. Si se llamó al método inflar con la especificación del contenedor para obtener la disposición del contenedor. parece que los casos son un problema porque en la segunda vez que sucedió, el contenedor anterior ya tiene una vista. por lo tanto, si se produce esa excepción, se detectará y devolverá la vista anterior contentView.

Cuestiones relacionadas