在項目中切換Fragment,一直都是用replace()方法來替換Fragment。但是這樣做有一個問題,每次切換的時候Fragment都會重新實列化,重新加載一次數據,這樣做會非常消耗性能用用戶的流量。
官方文檔解釋說:replace()這個方法只是在上一個Fragment不再需要時采用的簡便方法。
正確的切換方式是add(),切換時hide(),add()另一個Fragment;再次切換時,只需hide()當前,show()另一個。
這樣就能做到多個Fragment切換不重新實例化:
切換方法:
/**
* fragment 切換
*
* @param from
* @param to
*/
public void switchContent(Fragment from, Fragment to, int position) {
if (mContent != to) {
mContent = to;
FragmentTransaction transaction = fm.beginTransaction();
if (!to.isAdded()) { // 先判斷是否被add過
transaction.hide(from)
.add(R.id.content_frame, to, tags[position]).commit(); // 隱藏當前的fragment,add下一個到Activity中
} else {
transaction.hide(from).show(to).commit(); // 隱藏當前的fragment,顯示下一個
}
}
}
這樣做好后看似沒問題。但是比較低端的手機內存不足的時候會造成fragment重疊的情況。
實是由Activity被回收后重啟所導致的Fragment重復創建和重疊的問題。
在Activity onCreate()中添加Fragment的時候一定不要忘了檢查一下savedInstanceState:
多個Fragment重疊則可以這樣處理:通過FragmentManager找到所有的UI Fragment,按需要show()某一個Fragment,hide()其他即可!
為了能准確找出所需的Fragment,所以在add()或者replace() Fragment的時候記得要帶上tag參數,因為一個ViewGroup 容器可以依附add()多個Fragment,它們的id自然是相同的。
/**
* 狀態檢測 用於內存不足的時候保證fragment不會重疊
*
* @param savedInstanceState
*/
private void stateCheck(Bundle savedInstanceState) {
if (savedInstanceState == null) {
fm = getFragmentManager();
FragmentTransaction fts = fm.beginTransaction();
AnimationFragment af = new AnimationFragment();
mContent = af;
fts.add(R.id.content_frame, af);
fts.commit();
} else {
AnimationFragment af = (AnimationFragment) getFragmentManager()
.findFragmentByTag(tags[0]);
PlainFragment pf = (PlainFragment) getFragmentManager()
.findFragmentByTag(tags[1]);
RecordFragment rf = (RecordFragment) getFragmentManager()
.findFragmentByTag(tags[2]);
InformationFragment inf = (InformationFragment) getFragmentManager()
.findFragmentByTag(tags[3]);
TestingFragment tf = (TestingFragment) getFragmentManager()
.findFragmentByTag(tags[4]);
getFragmentManager().beginTransaction().show(af).hide(pf).hide(rf)
.hide(inf).hide(tf).commit();
}
}

