1

特定のビューがクリックされたときに、2 つのフラグメントを非表示および表示 (置換ではなく) 交換したい画面があります。これが私のコードです:

...
private Fragment currentFragment;
...
private void swapFragment(Fragment fragment) {
    FragmentTransaction ft = getChildFragmentManager().beginTransaction();

    if (currentFragment != null && !currentFragment.isHidden()) {
        ft.hide(currentFragment);
    }

    if (!fragment.isAdded()) {
        ft.add(R.id.fragment_holder, fragment);
    } else {
        ft.show(fragment);
    }
    ft.commit();

    currentFragment = fragment;
}
...

R.id.fragment_holderフレームレイアウトです。<fragment>レイアウトでタグを宣言しません。もともと私のスワップ方法はこれだけでした...

getChildFragmentManager().beginTransaction().replace(R.id.fragment_holder, fragment).commit();

...しかし、ここには入らない理由により、置換ではなく表示/非表示を行いたいと思います。

論理的には、これは非常に簡単です。フラグメントが表示されている場合は、最初に非表示にします。このフラグメントを初めて表示する場合は追加し、それ以外の場合は表示します。次に、現在のフラグメントを保存します。

IllegalStateException問題は最初の起動時にあり、フラグメントが既に追加されていることを示すメッセージが表示されてクラッシュしました。

11-12 08:36:49.098: E/AndroidRuntime(27293): FATAL EXCEPTION: main
11-12 08:36:49.098: E/AndroidRuntime(27293): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.my.package/com.my.package.activities.MainActivity}: java.lang.IllegalStateException: Fragment already added: ContactFragment{42263030 #0 id=0x7f0a006d}
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2324)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2374)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.app.ActivityThread.access$600(ActivityThread.java:154)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1248)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.os.Looper.loop(Looper.java:137)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.app.ActivityThread.main(ActivityThread.java:5242)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at java.lang.reflect.Method.invokeNative(Native Method)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at java.lang.reflect.Method.invoke(Method.java:511)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:799)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at dalvik.system.NativeStart.main(Native Method)
11-12 08:36:49.098: E/AndroidRuntime(27293): Caused by: java.lang.IllegalStateException: Fragment already added: ContactFragment{42263030 #0 id=0x7f0a006d}
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1175)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:616)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.support.v4.app.Fragment.performStart(Fragment.java:1499)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:957)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:1882)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:573)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at com.my.package.activities.MainActivity.onStart(MainActivity.java:252)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1164)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.app.Activity.performStart(Activity.java:5233)
11-12 08:36:49.098: E/AndroidRuntime(27293):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2287)
11-12 08:36:49.098: E/AndroidRuntime(27293):    ... 11 more
4

1 に答える 1

2

したがって、私の交換ロジックは問題なく機能することがわかりました。問題は、実際には、その子の間で 1 回のチェック変更に対して 2 回呼び出される可能性がRadioGroupあることです。これにより 2 つの が生成され、そのうちの 2 つ目は、既に追加されているフラグメントを追加しようとするため、IllegalStateException が発生します。OnCheckChangedListenerRadioButtonFragmentTransaction

私にとっての解決策は追加することでした

if (fragment == currentFragment) return;

の冒頭でswapFragment()

于 2013-11-12T17:47:24.533 に答える