官方文檔解釋說(shuō):replace()這個(gè)方法只是在上一個(gè)Fragment不再需要時(shí)采用的簡(jiǎn)便方法。
正確的切換方式是add(),切換時(shí)hide(),add()另一個(gè)Fragment;再次切換時(shí),只需hide()當(dāng)前,show()另一個(gè)。
這樣就能做到多個(gè)Fragment切換不重新實(shí)例化:
切換方法:
/**
* 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過(guò)
transaction.hide(from)
.add(R.id.content_frame, to, tags[position]).commit(); // 隱藏當(dāng)前的fragment,add下一個(gè)到Activity中
} else {
transaction.hide(from).show(to).commit(); // 隱藏當(dāng)前的fragment,顯示下一個(gè)
}
}
}
這樣做好后看似沒(méi)問(wèn)題。但是比較低端的手機(jī)內(nèi)存不足的時(shí)候會(huì)造成fragment重疊的情況。
實(shí)是由Activity被回收后重啟所導(dǎo)致的Fragment重復(fù)創(chuàng)建和重疊的問(wèn)題。
在ActivityonCreate()中添加Fragment的時(shí)候一定不要忘了檢查一下savedInstanceState:
多個(gè)Fragment重疊則可以這樣處理:通過(guò)FragmentManager找到所有的UI Fragment,按需要show()某一個(gè)Fragment,hide()其他即可!
為了能準(zhǔn)確找出所需的Fragment,所以在add()或者replace()Fragment的時(shí)候記得要帶上tag參數(shù),因?yàn)橐粋€(gè)ViewGroup 容器可以依附add()多個(gè)Fragment,它們的id自然是相同的。
/**
* 狀態(tài)檢測(cè) 用于內(nèi)存不足的時(shí)候保證fragment不會(huì)重疊
*
* @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();
}
}