IllegalStateException异常:无法更改片段的容器ID [英] IllegalStateException: Can't change container ID of Fragment

查看:656
本文介绍了IllegalStateException异常:无法更改片段的容器ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Android平台:3.1

Android platform: 3.1

我试图将一个片段容器中的一个容器B.这里沿用了code来实现:

I am trying to move a fragment from a container A to a container B. Here follows the code to accomplish this:

private void reattach(int newContainerId, Fragment frag, String tag) {

      if (frag == null || !frag.isAdded() || (frag.getId() == newContainerId)) { return; }

      final FragmentManager fm = getFragmentManager();
      FragmentTransaction ft = fm.beginTransaction();
      ft.remove(frag);     //stacco il frammento dal container A
      ft.commit();
      fm.executePendingTransactions();

      ft = fm.beginTransaction();
      ft.add(newContainerId, frag, tag); //attacco il frammento sul container D
      ft.commit();
      fm.executePendingTransactions();   
   }

当我运行的系统中,我得到了以下IllegalStateException异常:

When I run the system, I get the following IllegalStateException:

03-26 00:13:14.829: E/AndroidRuntime(30090): java.lang.RuntimeException: Unable to start activity ComponentInfo{eu.areamobile.apps.sfa/eu.areamobile.apps.sfa.activity.HomeActivity}: java.lang.IllegalStateException: Can't change container ID of fragment FragmentHomeController{408202a8 id=0x7f050010 HomeController}: was 2131034128 now 2131034132
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1751)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1767)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3117)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.ActivityThread.access$1600(ActivityThread.java:122)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1009)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.os.Looper.loop(Looper.java:132)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.ActivityThread.main(ActivityThread.java:4028)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at java.lang.reflect.Method.invokeNative(Native Method)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at java.lang.reflect.Method.invoke(Method.java:491)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at dalvik.system.NativeStart.main(Native Method)
03-26 00:13:14.829: E/AndroidRuntime(30090): Caused by: java.lang.IllegalStateException: Can't change container ID of fragment FragmentHomeController{408202a8 id=0x7f050010 HomeController}: was 2131034128 now 2131034132
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.BackStackRecord.doAddOp(BackStackRecord.java:338)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.BackStackRecord.add(BackStackRecord.java:316)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at eu.areamobile.apps.sfa.activity.HomeActivity.reattach(HomeActivity.java:340)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at eu.areamobile.apps.sfa.activity.HomeActivity.customHideShowCreate(HomeActivity.java:253)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at eu.areamobile.apps.sfa.activity.HomeActivity.customHideShowCreate(HomeActivity.java:155)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at eu.areamobile.apps.sfa.activity.HomeActivity.onPostCreate(HomeActivity.java:66)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.Instrumentation.callActivityOnPostCreate(Instrumentation.java:1111)
03-26 00:13:14.829: E/AndroidRuntime(30090):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1734)

在一个快速的调试,我注意到,在Android 3.1的FragmentTransaction.remove不为0的片段的mContainerId被删除,而在ICS它工作正常。
任何建议或解决方法?

After a quick debug, I noticed that on Android 3.1 the FragmentTransaction.remove doesn't set to 0 the mContainerId of the fragment being removed, while on ICS it works correctly.
Any suggestions or workarounds?

推荐答案

我解决这个问题的方法是重新创建片段,同时保持它的状态:

My solution to this problem is to re-create the fragment while keeping its state:

FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.remove(old);
Fragment newInstance = recreateFragment(old);
ft.add(R.id.new_container, newInstance);
ft.commit();

通过以​​下辅助函数:

With the following helper function:

private Fragment recreateFragment(Fragment f)
    {
        try {
            Fragment.SavedState savedState = mFragmentManager.saveFragmentInstanceState(f);

            Fragment newInstance = f.getClass().newInstance();
            newInstance.setInitialSavedState(savedState);

            return newInstance;
        }
        catch (Exception e) // InstantiationException, IllegalAccessException
        {
            throw new RuntimeException("Cannot reinstantiate fragment " + f.getClass().getName(), e);
        }
    }

这对我的作品,至少在最新的支持库(R11),虽然我没有测试很多呢。

It works for me, at least with the latest support library (r11), although I didn't test much yet.

额外的成本来实例化片段的两倍。

The extra cost is to instantiate the fragment twice.

这篇关于IllegalStateException异常:无法更改片段的容器ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆