在使用Activity管理多個Fragment時,每次切換Fragment使用的是replace,結果致使出現xxx is not currently in the FragmentManager異常掛掉java
網上說使用replace切換會使被切換的Fragment給替換掉,從而被被切換的Fragment的view從viewtree中刪除,導致切換過程當中每次都要從新建立Fragmentandroid
每次使用add添加Fragment,當再次切換到時用show顯示,而被切換的Fragment用hide隱藏,具體代碼以下:ide
1 /** 2 * Fragment跳轉 3 * @param fm 4 * @param fragmentClass 5 * @param tag 6 * @param args 7 */ 8 public void turnToFragment(Class<? extends Fragment> fromFragmentClass, Class<? extends Fragment> toFragmentClass, Bundle args) { 9 10 FragmentManager fm = getSupportFragmentManager(); 11 //被切換的Fragment標籤 12 String fromTag = fromFragmentClass.getSimpleName(); 13 //切換到的Fragment標籤 14 String toTag = toFragmentClass.getSimpleName(); 15 //查找切換的Fragment 16 Fragment fromFragment = fm.findFragmentByTag(fromTag); 17 Fragment toFragment = fm.findFragmentByTag(toTag); 18 //若是要切換到的Fragment不存在,則建立 19 if (toFragment == null) { 20 try { 21 toFragment = toFragmentClass.newInstance(); 22 toFragment.setArguments(args); 23 } catch (java.lang.InstantiationException e) { 24 e.printStackTrace(); 25 } catch (IllegalAccessException e) { 26 e.printStackTrace(); 27 } 28 } 29 //若是有參數傳遞, 30 if( args != null && !args.isEmpty() ) { 31 toFragment.getArguments().putAll(args); 32 } 33 //Fragment事務 34 FragmentTransaction ft = fm.beginTransaction(); 35 //設置Fragment切換效果 36 ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out, 37 android.R.anim.fade_in, android.R.anim.fade_out); 38 /** 39 * 若是要切換到的Fragment沒有被Fragment事務添加,則隱藏被切換的Fragment,添加要切換的Fragment 40 * 不然,則隱藏被切換的Fragment,顯示要切換的Fragment 41 */ 42 if( !toFragment.isAdded()) { 43 ft.hide(fromFragment).add(R.id.content_frame, toFragment, toTag); 44 } else { 45 ft.hide(fromFragment).show(toFragment); 46 } 47 //添加到返回堆棧 48 // ft.addToBackStack(tag); 49 //不保留狀態提交事務 50 ft.commitAllowingStateLoss(); 51 }
這裏有個FragmentTransaction(事務),這個是Fragment切換的核心類,它有兩個方法:replace,add,一個是替換Fragment,一個是添加Fragment,二者的區別是:replace=remove掉舊fragment,add新的fragment,spa
當咱們的應用(即管理多個Fragment的Activity)運行到後臺時(即推出當前屏幕),會觸發Activity的onPause()方法,而Activity的onPause()會調用它所管理的Fragment的一樣的方法,可是當我使用replace時,已經remove掉了原來的Fragment,因此當調用原理的Fragment的onPause()方法就回不粗在,就會出現上述xxx is not currently in the FragmentManager的異常推出,有debug爲證:debug