問題
當快速點擊切換不同的Fragment的時候部分手機的app竟然掛了鳍怨,報出了下面的錯誤
java.lang.IllegalStateException: Fragment already added: xxxxFragment
上網(wǎng)找了很多,大致得到的原因是當快速雙擊調用FragmentTransaction.add()方法添加fragmentA,而fragmentA不是每次單獨生成的,就會引起這個異常鸵钝。
上面的內容是網(wǎng)上的解釋济炎,不過我認為是因為同一個Fragment被add兩次導致的錯誤,但是奇怪的是我在加載這個Fragment的時候已經(jīng)做了是否add的判斷沸伏,為什么還會有這個問題呢。
private void addFragment(FragmentManager fm, Fragment fragment ) {
Log.i( "addFragment", "### " + fragment.getId() + " " + fragment.isAdded() + " " + fragment.isHidden() );
if (!fragment.isAdded() ) {
FragmentTransaction ft = fm.beginTransaction();
fm.executePendingTransactions();
ft.add( R.id.main_content, fragment );
ft.commitAllowingStateLoss();
}
通過打印結果發(fā)現(xiàn)动分,第一次切換到FragmentA的時候毅糟,F(xiàn)ragmentA明明已經(jīng)add了,但是isAdded()依然顯示false
addFragment: ###1 2131755357 false true
addFragment: ###2 2131755357 false true
addFragment: ###3 2131755357 false true
addFragment: ###4 2131755357 false true
第二次切換到相同F(xiàn)ragmentA的時候isAdded()就顯示為true了
addFragment: ###1 2131755357 true true
addFragment: ###2 2131755357 true true
addFragment: ###3 2131755357 true true
addFragment: ###4 2131755357 true true
在不斷快速切換不同的Fragment的時候澜公,isAdded()偶爾會顯示false姆另,就因為isAdded()顯示了false,那么 ft.add( R.id.main_content, fragment )就會再次執(zhí)行一次坟乾,就會報錯迹辐,說明通過isAdded()這個方法判斷Fragment是否被add可能并不準確。
方法
解決方法就是每次add的時候加上一個tag糊渊,然后不僅要通過isAdded()判斷Fragment是否add右核,還要通過FragmentManager.findFragmentByTag(tag)獲取Fragment,然后判斷此Fragment是否為null渺绒。
case R.id.home_tab_a:
hideAllFragment( fm );
addFragment( fm, fragmentA, "A" );
showFragment( fm, fragmentA );
break;
case R.id.home_tab_b:
hideAllFragment( fm );
addFragment( fm, fragmentB, "B" );
showFragment( fm, fragmentB );
break;
case R.id.home_tab_c:
hideAllFragment( fm );
addFragment( fm, fragmentC, "C" );
showFragment( fm, fragmentC );
break;
影藏所有的Fragment
private void hideAllFragment(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction();
if (!shijianFragment.isHidden())
ft.hide( fragmentA );
if (!riliFragment.isHidden())
ft.hide( fragmentB );
if (!gongjuFragment.isHidden()) {
ft.hide( fragmentC );
}
ft.commitAllowingStateLoss();
}
通過isAdded()判斷Fragment是否add贺喝,同時通過tag獲取Fragment,判斷Fragment是否為空宗兼,雙重判斷
private void addFragment(FragmentManager fm, Fragment fragment, String tag) {
if (!fragment.isAdded()&&null == fm.findFragmentByTag( tag )) {
FragmentTransaction ft = fm.beginTransaction();
fm.executePendingTransactions();
ft.add( R.id.main_content, fragment, tag );
ft.commitAllowingStateLoss();
}
}
顯示Fragment
private void showFragment(FragmentManager fm, Fragment fragment) {
FragmentTransaction ft = fm.beginTransaction();
ft.show( fragment );
ft.commitAllowingStateLoss();
}