簡體   English   中英

PagerAdapter.getItem() 崩潰並出現 IllegalStateException:已添加片段

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

我有 FragmentStatePagerAdapter.getItem() 的代碼:

(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;
}

但它不斷崩潰:

    --------- 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)

這讓我完全難住了。 有人可以幫助為什么會發生這種崩潰嗎?

據我所知,相同的代碼結構可以在我的應用程序的其他地方使用。

我確實看到了其他幾個具有相同例外的 SO 問題,但沒有一個專門針對 ViewPager+TabLayout 組合中的片段。

編輯:即使此代碼也因相同的異常而崩潰:

@Override
public Fragment getItem(int position) {

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

編輯:添加 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;
}

編輯:

似乎如果我從 getItem() 返回 new Fragment(),一切正常。 如果我從 getItem() 返回 new MyCustomFragment(),我會崩潰。 MyCustomFragment 甚至沒有任何構造函數; 它依賴於默認的(盡管我確實嘗試了一個只調用 super(); 的無參數構造函數;但崩潰仍然存在)。

您不能在其他地方使用已添加的Fragment 當這行代碼執行時:

currFragment = allFragments.get(position);

根據log ,這意味着您列表中的fragment已經添加到某處(在不同的地方或相同的地方)。 換句話說,在getItem(int position)中,您只能添加Fragment的新實例。 所以刪除這個代碼塊:

else {

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

而這個exception應該 go 掉了。

問題是在 MyCustomFragment 中,在 onCreateView() 方法中, return super.onCreateView()的 IDE 存根代碼被無意中留在了原處。 超類 Fragment 在特定條件下從其 onCreateView() 返回 null。 從 onCreateView() 返回的 null 似乎造成了問題。 我在 MyCustomFragment 的 onCreateView() 中膨脹了一個測試布局,現在崩潰已經消失了。

如果確實如此,則異常看起來措辭不正確。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM