为啥popbackstack会调用fragment的onCreateView?

Posted

技术标签:

【中文标题】为啥popbackstack会调用fragment的onCreateView?【英文标题】:Why does popbackstack call onCreateView of the fragment?为什么popbackstack会调用fragment的onCreateView? 【发布时间】:2014-03-09 16:00:54 【问题描述】:

试图弄清楚为什么在我 popbackstack 片段时调用 onCreateView。

使用以下代码:

fragmentManager.popBackStack("tag1", 1); 
ft = fragmentManager.beginTransaction(); 
ft.remove(fragmentManager.findFragmentByTag("tag1")); 
ft.commit();

Logcat:

FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 79, size is 79
        at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
        at java.util.ArrayList.get(ArrayList.java:308)
        at edu.pacific.pocketrx.FlashCardFrag.onCreateView(FlashCardFrag.java:72)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
        at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:764)
        at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1562)
        at android.support.v4.app.FragmentManagerImpl$3.run(FragmentManager.java:495)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
        at android.os.Handler.handleCallback(Handler.java:730)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5103)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)

删除片段的代码:

fragmentManager.popBackStack("tag1", 1);
ft = fragmentManager.beginTransaction();
ft.remove(fragmentManager.findFragmentByTag("tag1"));
ft.commit();

【问题讨论】:

您能详细说明一下吗?也许有一些代码? onCreateView 当然会在前一个片段上调用,如果 backstack 把你放在那里.. 您能否将您的 logcat 粘贴到问题中 - 它更容易阅读 【参考方案1】:

实际上片段管理器不存储您的隐藏片段它只存储一个状态

类 BackStackState 实现 Parcelable

见http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/support/v4/app/FragmentManager.java#FragmentManagerImpl.popBackStackState%28android.os.Handler%2Cjava.lang.String%2Cint%2Cint%29

当你弹出一个片段时,片段管理器会尝试重新创建以前的视图来显示它。

查看 moveToState 方法

【讨论】:

你能澄清一下吗? @veon,有没有办法从堆栈中删除片段而不重新创建前一个片段?如果我想一次删除多个片段,或者只想用新片段替换堆栈怎么办?【参考方案2】:

更新:请忽略这个答案,这显然是错误的,我不知道我在说什么(那是 3 年前!)

原始(不正确)答案:

在我的情况下,我在后堆栈上有 2 个片段,调用它:

FragmentManager fm = activity.getSupportFragmentManager();
            fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

似乎会触发onCreateView(),即使是顶部的当前片段也很混乱。我已将其替换为 popBackStackImmediate:

FragmentManager fm = activity.getSupportFragmentManager();
        fm.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

并且 onCreateView() 现在不再为顶部片段调用。

【讨论】:

onCreateView() 仍在为我调用,即使在开始使用 popBackStackImmediate() 之后也是如此。

以上是关于为啥popbackstack会调用fragment的onCreateView?的主要内容,如果未能解决你的问题,请参考以下文章

在 PopBackStack 之后片段弹出调用 OnViewCreated

Navigation Components popBackStack() 是不是保留 Fragment 状态?

Navigation popBackStack 禁用进一步导航到此 Fragment

Android FragmentTabHost popBackStack() 导致 IllegalStateException Fragment 已添加

片段 PopBackStack

FragmentManager popBackStack 不删除片段