FATAL EXCEPTION: main
Process: com.example.loan, PID: 24169
java.lang.IllegalStateException: Fragment already added: FormFragment{428f10c8 #1 id=0x7f050055 form}
at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1192)
at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:722)
at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1533)
at android.support.v4.app.FragmentManagerImpl$2.run(FragmentManager.java:489)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:450)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5068)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
at dalvik.system.NativeStart.main(Native Method)
Entonces, tengo una aplicación de Android que se construye con tabhost. Hay tres pestañas en total, en la pestaña2, hay un botón para realizar la transacción del fragmento en la pestaña2 (que está llamando a la función en la actividad del fragmento)
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.realtabcontent, mFrag);
t.addToBackStack(null);
t.commit();
Hay una excepción si corro así:
- Dentro de la pestaña 2, presiono el botón para cambiar el fragmento
- Ir a otra pestaña (por ejemplo, pestaña 1 o pestaña 3)
- Presione el botón de retroceso
- Lanzar excepción
¿Cómo arreglar eso? Gracias por ayudar
android
android-fragments
tabs
android-lifecycle
fragment-tab-host
usuario782104
fuente
fuente
Respuestas:
Esto sucede cuando intentamos agregar el mismo fragmento o DialogFragment dos veces antes de descartar,
solo llama
if(mFragment.isAdded()) { return; //or return false/true, based on where you are calling from }
Habiendo dicho eso, no veo ninguna razón por la que eliminar el fragmento antiguo y agregar el mismo fragmento nuevamente, ya que podemos actualizar la interfaz de usuario / datos simplemente pasando parámetros al método dentro del fragmento
fuente
isAdded()
. En segundo lugar, en los comentarios, se sugiere que este código se incluyaonCreate()
, lo que también es absurdo. Esta línea de código debe colocarse directamente antes de la línea donde se agrega (o reemplaza) el fragmento, no enonCreate()
oonCreateView()
. Es demasiado tarde para ejecutar ese código en cualquiera de esos métodos.if(fragment.isAdded()) fragmentTransaction.show(fragment);
Elimine el fragmento antiguo en caso de que aún se agregue y luego agregue el nuevo fragmento:
FragmentManager fm = getSupportFragmentManager(); Fragment oldFragment = fm.findFragmentByTag("fragment_tag"); if (oldFragment != null) { fm.beginTransaction().remove(oldFragment).commit(); } MyFragment newFragment = new MyFragment(); fm.beginTransaction().add(newFragment , "fragment_tag");
fuente
setArguments
, me refería a enviar argumentos como parámetros para actualizar, por lo que eliminar y agregar el mismo fragmento no tiene ningún uso, ¿verdad?Solo tiene que verificar una condición en su fragmento que se menciona a continuación:
if(!isAdded()) { return; }
isAdded = Devuelve verdadero si el fragmento se agrega actualmente a su actividad. Tomado del documento oficial. Esto no agregará ese fragmento si ya está agregado
Consulte el siguiente enlace para obtener una referencia:
http://developer.android.com/reference/android/app/Fragment.html#isAdded ()
fuente
onCreate
?A veces sucede por no encontrar la identificación adecuada en el diseño respectivo. Me enfrenté a este problema. Luego, después de muchas horas, descubrí que configuré una identificación de reciclaje incorrecta. Lo cambio y funciona bien para mí.
Entonces, revise el diseño de su fragmento.
fuente
Solo tiene que verificar una condición antes de comenzar la transacción del fragmento
if (!fragmentOne.isAdded()){ transaction = manager.beginTransaction(); transaction.add(R.id.group,fragmentOne,"Fragment_One"); transaction.commit(); }
esto está funcionando perfectamente para mí ...
fuente
Tengo este error cuando no envuelvo el XML de mi cuerpo dentro de un ViewGroup dentro de FrameLayout.
Error:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".screens.home.HomeEpoxyFragment"> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/swipe_refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv" android:overScrollMode="never" android:layout_width="match_parent" android:layout_height="match_parent" /> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </FrameLayout>
Resuelto:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".screens.home.HomeEpoxyFragment"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/swipe_refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv" android:overScrollMode="never" android:layout_width="match_parent" android:layout_height="match_parent" /> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.constraintlayout.widget.ConstraintLayout> </FrameLayout>
Espero que esto pueda ayudar a alguien.
fuente
Para mi funciona como:
Fragment oldFragment = manager.findFragmentByTag(READER_VIEW_POPUP); if (oldFragment != null) { manager.beginTransaction().remove(oldFragment).commit(); } FragmentTransaction ft = manager.beginTransaction(); ft.add(this, tag); ft.commit();
fuente
Incluso puede ocurrir si en
FragmentStatePagerAdapter
tuViewPager
creas un artículo que ya existe:override fun getItem(position: Int): Fragment { return tabs[0] // Right variant: tabs[position] }
(
private val tabs: List<Fragment>
es una lista de fragmentos en pestañas).fuente
return tabs[position]
en la segunda línea.return tabs[position]
pero todavía arroja un errorFragmentStatePagerAdapter
arroja el errorgetItem
?ViewPager
se recuperan las instancias de los fragmentos mostrados por elPara mi sorpresa, cometí un error estúpido al llamar dos veces a la transacción del fragmento:
if (!FirebaseManager.isClientA && !FirebaseManager.isClientB) { fragment = new FragmentA(); getFragmentManager().beginTransaction().add(R.id.fragment_frame, fragment, null).addToBackStack("").commit(); } else if (FirebaseManager.isClientB) { fragment = new FragmentB(); } else { fragment = new FragmentC(); } getFragmentManager().beginTransaction().add(R.id.fragment_frame, fragment, null).addToBackStack("").commit();
Asegúrese de no cometer el mismo error.
fuente
Agregar fragmento como se muestra a continuación
FragmentTransaction t = getSupportFragmentManager().beginTransaction(); t.replace(R.id.realtabcontent, mFrag); t.addToBackStack(null); t.commitNowAllowingStateLoss();
fuente
addToBackStack
no está permitido junto concommitNow
.Puedes probar esto:
if (dialogFolderGallery.isAdded()) { dialogFolderGallery.dismiss(); } else { //bla...bla.. }
fuente
Recibí este error cuando usé incorrectamente mi ViewModel dentro de Fragment como este:
//This is wrong! MyViewModel viewModel = new MyViewModel(getActivity().getApplication());
Manera correcta:
viewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(MyViewModel.class);
fuente
Aquí mi solución para Fragmento de diálogo (puede usar este concepto también para la clase de fragmento)
He intentado hacer clic en mostrar fragmento de diálogo pulsando el botón varias veces y rápidamente.
FragmentManager fm = getSupportFragmentManager(); Fragment oldFragment = fm.findFragmentByTag("wait_modal"); if(oldFragment != null && oldFragment.isAdded()) return; if(oldFragment == null && !please_wait_modal.isAdded() && !please_wait_modal.isVisible()){ fm.executePendingTransactions(); please_wait_modal.show(fm,"wait_modal"); }
fuente