gpt4 book ai didi

android - 非法状态异常 : Can't change container ID of Fragment

转载 作者:IT老高 更新时间:2023-10-28 22:06:39 29 4
gpt4 key购买 nike

安卓平台:3.1

我正在尝试将 fragment 从容器 A 移动到容器 B。下面是完成此操作的代码:

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:

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 没有将要删除的 fragment 的 mContainerId 设置为 0,而在 ICS 上它可以正常工作。
有什么建议或解决方法吗?

最佳答案

我对这个问题的解决方案是在保持其状态的同时重新创建 fragment :

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

使用以下辅助函数:

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),虽然我还没有测试太多。

额外的成本是两次实例化 fragment 。

关于android - 非法状态异常 : Can't change container ID of Fragment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9906254/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com