[android] IllegalStateException : 조각이 이미 탭 호스트 조각에 추가되었습니다.

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)

그래서 탭 호스트로 빌드하는 Android 앱이 있습니다. 총 3 개의 탭이 있습니다. tab2에는 tab2에서 조각 트랜잭션을 만드는 버튼이 있습니다 (조각 활동에서 함수를 호출 함).

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

다음과 같이 실행하면 예외가 있습니다.

  1. tab2 내부에서 버튼을 눌러 조각을 변경합니다.
  2. 다른 탭으로 이동 (예 : 탭 1 또는 탭 3)
  3. 뒤로 버튼 누르기
  4. 예외 발생

어떻게 고칠까요? 도움을 주셔서 감사합니다



답변

이것은 닫히기 전에 동일한 조각 또는 DialogFragment를 두 번 추가하려고 할 때 발생합니다.

그냥 전화 해

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

그렇다고해서 이전 프래그먼트를 제거하고 동일한 프래그먼트를 다시 추가해야하는 이유는 알 수 없습니다. 단순히 프래그먼트 내부의 메서드에 매개 변수를 전달하여 UI / 데이터를 업데이트 할 수 있기 때문입니다.


답변

여전히 추가 된 경우 이전 조각을 제거한 다음 새 조각을 추가합니다.

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


답변

아래에 언급 된 조각에서 하나의 조건 만 확인하면됩니다.

if(!isAdded())
{
    return;
}

i Added = 조각이 현재 활동에 추가 된 경우 true를 반환합니다. 공식 문서에서 가져 왔습니다. 이미 추가 된 경우 해당 조각을 추가하지 않습니다.

참조는 아래 링크를 확인하십시오.
http://developer.android.com/reference/android/app/Fragment.html#i Added ()


답변

때로는 각 레이아웃에서 적절한 ID를 찾지 못하는 경우가 있습니다. 나는이 문제에 직면했다. 그런 다음 몇 시간 후에 잘못된 recyclerview ID를 설정했음을 발견했습니다. 나는 그것을 바꾸고 잘 작동합니다.

따라서 조각 레이아웃을 다시 확인하십시오.


답변

프래그먼트 트랜잭션을 시작하기 전에 하나의 조건 만 확인하면됩니다.

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

이것은 나를 위해 perfactly 작동합니다 …


답변

FrameLayout 내의 ViewGroup 내부에 내 본문 XML을 래핑하지 않을 때이 오류가 발생합니다.

오류:

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

해결됨 :

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

이것이 누군가를 도울 수 있기를 바랍니다.


답변

나를 위해 그것은 다음과 같이 작동합니다.

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