Obtener error al agregar fragmentos dinámicamente -java.lang.illegalstateException:
-
26-10-2019 - |
Pregunta
Estoy trabajando en 3.0 por primera vez. Yo quiero Agregar fragmentos dinámicamente , Pero su error se muestra:-
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;
}
}
Por favor pon un poco de luz, donde me estoy equivocando :(
Solución
En lugar de usar
View l = inflater.inflate(R.layout.textlay,container);
Deberías usar
View l = inflater.inflate(R.layout.textlay, container, false);
o alternativamente
View l = inflater.inflate(R.layout.textlay, null );
Le sugiero encarecidamente que use, la versión de inflate
que toma tres parámetros. Android usa el contenedor solo para el propósito de los parámetros del diseño. Paso false
Como tercer parámetro, evita la adición de textlay
, a container
y soluciona tu problema
Otros consejos
Si en OnCreateView (), desea reutilizar la vista, entonces puede tratar con OnDestroyView ()
@Override
public void onDestroyView() {
super.onDestroyView();
if (view != null) {
ViewGroup parentViewGroup = (ViewGroup) view.getParent();
if (parentViewGroup != null) {
parentViewGroup.removeAllViews();
}
}
}
O puede usar el tercer argumento y pasarlo como falso.
inflater.inflate(R.layout.sample_fragment, container,false);
Significa que no adjunta la vista actual a la raíz.
Lo siguiente resuelve múltiples 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();
}
}
}
}
Si los fragmentos se muestran con animación y usuario obligados a repetir la animación antes de que termine. Ej: Botón de presentación del menú dos veces antes de que el fragmento de menú termine de animar y aparecer. (Esto fue resuelto por OnDestryView de User2764384)
Si se llama al método de inflado, especificando el contenedor para obtener la salida del contenedor. Parece que los casos son un problema porque en la segunda vez que sucedió el antiguo contenedor ya tiene una vista. Entonces, si esa excepción ocurre, se atrapará y devuelve la vista de contenido de vista anterior.