[英]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.