简体   繁体   English

PagerAdapter.getItem() 崩溃并出现 IllegalStateException:已添加片段

[英]PagerAdapter.getItem() crash with IllegalStateException: Fragment already added

I have this code for FragmentStatePagerAdapter.getItem():我有 FragmentStatePagerAdapter.getItem() 的代码:

(logd() is just a static method that calls Log.d()). (logd() 只是一个调用 Log.d() 的 static 方法)。

@Override
public Fragment getItem(int position) {

    logd("Fragment for position: " + position);

    Fragment currFragment = null;
    List<Fragment> allFragments = mFragmentManager.getFragments();
    if (allFragments.size() == 0) {

        logd("No Fragments cached.");
    } else {

        currFragment = allFragments.get(position);
        logd("Found a cached Fragment: " + currFragment);
    }

    if (currFragment == null) {

        currFragment = MyCustomFragment.create(position);
    }

    logd("Returning Fragment: Position: " + position + " Fragment: " + currFragment.toString());
    return currFragment;
}

But it keeps crashing with:但它不断崩溃:

    --------- beginning of crash
2020-07-27 10:45:44.492 6271-6271/com.example.package E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.package, PID: 6271
    java.lang.IllegalStateException: Fragment already added: MyCustomFragment{7c7e778} (5f284a0f-a00f-4be2-8098-a3e8dc65c9cb) id=0x7f09024e}
        at androidx.fragment.app.FragmentStore.addFragment(FragmentStore.java:67)
        at androidx.fragment.app.FragmentManager.addFragment(FragmentManager.java:1563)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:405)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6592)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)

This has me totally stumped.这让我完全难住了。 Can someone help why this crash is happening?有人可以帮助为什么会发生这种崩溃吗?

As far as I can make out, the same code construct works elsewhere in my app.据我所知,相同的代码结构可以在我的应用程序的其他地方使用。

I did see several other SO questions with the same exception, but none that dealt specifically with Fragments inside ViewPager+TabLayout combinations.我确实看到了其他几个具有相同例外的 SO 问题,但没有一个专门针对 ViewPager+TabLayout 组合中的片段。

Edit: Even this code crashes with the same exception:编辑:即使此代码也因相同的异常而崩溃:

@Override
public Fragment getItem(int position) {

    Fragment currFragment = MyCustomFragment.create(position);
    logd("Returning Fragment: Position: " + position + " Fragment: " + currFragment.toString());
    return currFragment;
}

Edit: Adding the code of MyCustomFragment.create():编辑:添加 MyCustomFragment.create() 的代码:

public static MyCustomFragment create(int position) {

    Bundle args = new Bundle();
    args.putInt("position", position);
    MyCustomFragment f = new MyCustomFragment();
    f.setArguments(args);
    logd("Creating Fragment at position: " + position);
    return f;
}

Edit:编辑:

It seems that if I return new Fragment() from getItem(), everything works.似乎如果我从 getItem() 返回 new Fragment(),一切正常。 If I return new MyCustomFragment() from getItem(), I get the crash.如果我从 getItem() 返回 new MyCustomFragment(),我会崩溃。 MyCustomFragment does not even have any constructor; MyCustomFragment 甚至没有任何构造函数; it relies on the default one (though I did try with a no-arg constructor that just calls super(); still the crash persists).它依赖于默认的(尽管我确实尝试了一个只调用 super(); 的无参数构造函数;但崩溃仍然存在)。

You cannot use an already added Fragment in another place.您不能在其他地方使用已添加的Fragment When this line of code is executing:当这行代码执行时:

currFragment = allFragments.get(position);

according to the log , it means the fragment in you list is already added somewhere (in a different place or very same place).根据log ,这意味着您列表中的fragment已经添加到某处(在不同的地方或相同的地方)。 In other words, in getItem(int position) , you can only add a new instance of a Fragment .换句话说,在getItem(int position)中,您只能添加Fragment的新实例。 So remove this code block:所以删除这个代码块:

else {

    currFragment = allFragments.get(position);
    logd("Found a cached Fragment: " + currFragment);
}

And this exception should go away.而这个exception应该 go 掉了。

The problem was that within MyCustomFragment, in the onCreateView() method, the IDE-stub code of return super.onCreateView() was left in place inadvertently.问题是在 MyCustomFragment 中,在 onCreateView() 方法中, return super.onCreateView()的 IDE 存根代码被无意中留在了原处。 The superclass, Fragment, returns null from its onCreateView() under certain conditions.超类 Fragment 在特定条件下从其 onCreateView() 返回 null。 It appears that this null return from onCreateView() was creating the problem.从 onCreateView() 返回的 null 似乎造成了问题。 I inflated a test layout in MyCustomFragment's onCreateView() and now the crash is gone.我在 MyCustomFragment 的 onCreateView() 中膨胀了一个测试布局,现在崩溃已经消失了。

The exception looks incorrectly worded if that is indeed the case.如果确实如此,则异常看起来措辞不正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM