55

コンテナーのアクティビティでこのメソッドを使用して、BFrag を表示します。

public void showBFrag()
{
    // Start a new FragmentTransaction
    FragmentTransaction fragmentTransaction = mFragmentMgr.beginTransaction();

    if(mBFrag.isAdded())
    {
        Log.d(LOG_TAG, "Show() BFrag");
        fragmentTransaction.show(mBFrag);   
    }
    else
    {
        Log.d(LOG_TAG, "Replacing AFrag -> BFrag");
        fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);
    }

    // Keep the transaction in the back stack so it will be reversed when backbutton is pressed
    fragmentTransaction.addToBackStack(null);

    // Commit transaction
    fragmentTransaction.commit();        
}

コンテナーのアクティビティから呼び出します。初めて:

  • else ステートメントに入り、mBFrag が mAFrag を置き換えます。

次に、戻るボタンを押します。

  • 操作が逆になります (mAFrag が表示されますが、mBFrag は削除されますか?)。

次に、同じアクティビティから showBFrag() を呼び出して、再び先に進みます。

  • そして、else ステートメントに再び入ります。(したがって、mBFrag は追加されていないと推測できます)
  • しかし、フラグメントが既に追加されている IllegalStateExceptionを取得しました...(では、代わりに if ステートメントに入らなかったのはなぜですか?)

そう:

  1. Fragment already added IllegalStateExceptionを取得している場合、isAdded() メソッドが TRUE を返さないのはなぜですか??
  2. popBackStack 操作は、以前に追加されたフラグメントを完全に削除しますか?
  3. 私が誤解している行動は何ですか?

編集:例外の完全な情報は次のとおりです。

06-07 12:08:32.730: ERROR/AndroidRuntime(8576): java.lang.IllegalStateException: Fragment already added: BFrag{40b28158 id=0x7f0c0085}
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.doAddOp(BackStackRecord.java:322)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:360)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at android.app.BackStackRecord.replace(BackStackRecord.java:352)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at myPackageName.containerActivity.showBFrag() // This line: "fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);"
4

11 に答える 11

43

結局、私の回避策は、前のフラグメントのremove()を実行し、新しいフラグメントをadd()することでした。それがreplace()メソッドが行うことを意図していたことですが。

しかし、この場合、replace()メソッドが正しく機能しなかった理由はまだ推測できます。それは本当に奇妙で、私が何かを誤解している、または何か間違ったことをしているからだということを捨てたいと思います。

于 2011-06-07T13:44:19.183 に答える
12

アクティビティの状態が既に保存されている場合、commit を呼び出すのはもはや安全ではありません。commitAllowingStateLoss()代わりに電話する必要があります。お役に立てれば!

編集:わかりました、問題を詳しく調べました。問題は、既に追加されているフラグメントを追加しようとしていることです。replace または remove 呼び出しを使用しても、これを行うことはできません。私が見つけた回避策は、フラグメントの新しいインスタンスを作成して毎回追加することだけです。フラグメントを削除または置換したら、そのフラグメントへのすべての参照を削除して、GC が処理できるようにすることをお勧めします。

于 2011-06-06T15:04:43.247 に答える
8

おそらくこの問題とは直接関係ありませんが、FragmentTransaction への遷移を設定すると IllegalStateException が発生し、遷移を設定しないと発生しないことにも気付きました。

この問題のバグは次のとおりです: http://code.google.com/p/android/issues/detail?id=25598

于 2012-02-16T08:43:06.400 に答える
1

setOffscreenPageLimitから削除するとViewpager、問題が解決しました。ありがとう。

于 2016-08-17T10:36:21.853 に答える
1

fragmentTransection.replace() の後にこれを試してください

fragmentTransection.addToBackStack(null);
fragmentTransection.commitAllowingStateLoss();
于 2015-05-02T11:36:34.163 に答える
0

このコードは私にとってはうまく機能しています。これを試して

((MiActivity)getActivity()).addAccount = new AddAccount();
((MiActivity)getActivity()).addAccount.setArguments(params);
fragmentManager = getActivity().getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container((MiActivity)getActivity()).addAccount);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
于 2014-01-04T12:23:48.347 に答える
0

フラグメントをループして isAdded() が true かどうかを確認し、そのフラグメントを削除することで解決しました。詳細はこちら。

于 2014-09-29T06:48:15.703 に答える
0

FragmentTransaction.remove()から呼び出してみonTabUnselected()ましたが、このバグを回避しました。

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    ft.add(R.id.fragment_container, fragment, null);
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    ft.remove(fragment);
}
于 2013-03-11T09:55:31.263 に答える