IllegalStateException: Fragment already added in the tabhost fragment

AndroidAndroid FragmentsTabsAndroid LifecycleFragment Tab-Host

Android Problem Overview


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)

So, I have an android app that build with the tabhost. There are three tabs in total, in the tab2, there is a button to make the fragment transaction in tab2 (which is calling the function in the fragment activity)

FragmentTransaction t = getSupportFragmentManager().beginTransaction();
		t.replace(R.id.realtabcontent, mFrag);
		t.addToBackStack(null);
		t.commit();

There is exception if I run like this:

  1. Inside the tab2, I press the button to change fragment
  2. Go to other tab (eg. tab 1 or tab 3)
  3. Press back button
  4. Throw exception

How to fix that? Thanks for helping

Android Solutions


Solution 1 - Android

This happens when we try to add same fragment or DialogFragment twice before dismissing,

just call

if(mFragment.isAdded())
{
     return; //or return false/true, based on where you are calling from
}

Having said that, I don't see any reason why to remove old fragment and add the same fragment again since we can update the UI/data by simply passing parameters to the method inside the fragment

Solution 2 - Android

Remove the old fragment in case it is still added and then add the new fragment:

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");

Solution 3 - Android

You just have to check one condition in your fragment mentioned below:

if(!isAdded())
{
	return;
}

isAdded = Return true if the fragment is currently added to its activity. Taken from the official document. This will not add that fragment if it is already added

Check below link for a reference:
http://developer.android.com/reference/android/app/Fragment.html#isAdded()

Solution 4 - Android

Sometimes it happens for not finding proper id from the respective layout. I faced this problem. Then after many hours I found that I set wrong recyclerview id. I change it, and works fine for me.

So, double check your fragment layout.

Solution 5 - Android

You just have to check one condition before start fragment transaction

 if (!fragmentOne.isAdded()){
            transaction = manager.beginTransaction();
            transaction.add(R.id.group,fragmentOne,"Fragment_One");
            transaction.commit();
 }

this is working perfactly for me...

Solution 6 - Android

I have this error when not wrapping my body XML inside a ViewGroup inside 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>

Solved:

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

Hope this may help someone.

Solution 7 - Android

Here my solution for Dialog Fragment (you can use this concept also for fragment class)

I have try to click show dialog fragment by tap button multiple time and quickly.

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");
}

Solution 8 - Android

For me it works like:

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();

Solution 9 - Android

It even can occur if in FragmentStatePagerAdapter of your ViewPager you create an item that already exists:

override fun getItem(position: Int): Fragment {
    return tabs[0] // Right variant: tabs[position]
}

(private val tabs: List<Fragment> is a list of fragments in tabs).

Solution 10 - Android

To my surprise, I made stupid mistake by calling the fragment transaction twice:

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();

Make sure you don't make the same mistake.

Solution 11 - Android

Add Fragment as below

FragmentTransaction t = getSupportFragmentManager().beginTransaction();
    t.replace(R.id.realtabcontent, mFrag);
    t.addToBackStack(null);
    t.commitNowAllowingStateLoss();

Solution 12 - Android

You can try this:

 if (dialogFolderGallery.isAdded()) {
                dialogFolderGallery.dismiss();
            } else { //bla...bla..
}

Solution 13 - Android

I got this error when incorrectly used my ViewModel inside of Fragment like this:

//This is wrong!
MyViewModel viewModel = new MyViewModel(getActivity().getApplication());

Correct way:

viewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(MyViewModel.class);

Solution 14 - Android

not good solving, but it work)

if(!ConfirmDataSync.isVisible) show()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser782104View Question on Stackoverflow
Solution 1 - AndroidUjjuView Answer on Stackoverflow
Solution 2 - AndroidvovahostView Answer on Stackoverflow
Solution 3 - AndroidDeep MehtaView Answer on Stackoverflow
Solution 4 - AndroidMihabView Answer on Stackoverflow
Solution 5 - AndroidMehul SolankiView Answer on Stackoverflow
Solution 6 - AndroidDung NguyenView Answer on Stackoverflow
Solution 7 - AndroidYohanimView Answer on Stackoverflow
Solution 8 - AndroidFarid HaqView Answer on Stackoverflow
Solution 9 - AndroidCoolMindView Answer on Stackoverflow
Solution 10 - AndroidSetoView Answer on Stackoverflow
Solution 11 - AndroidMuhammad NomanView Answer on Stackoverflow
Solution 12 - AndroidMr. LemonView Answer on Stackoverflow
Solution 13 - AndroidKamil RadzView Answer on Stackoverflow
Solution 14 - Androiduser12927542View Answer on Stackoverflow