ANDROID FRAMENT的切換(解決REPLACE的低效)
阿新 • • 發佈:2019-02-15
原博主:https://www.cnblogs.com/android-joker/p/4414891.html
在專案中切換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(); } }