前言
前段時間在工作中遇到了fragment的重疊問題,耽誤了挺久的,主要原因還是在于自己對fragment的研究還不夠深入,隻是一些泛泛的了解。
重疊問題出現的原因
當我使用show和hide來控制fragment的顯隐時,一旦作為容器的activity被系統GC,導緻activity的所有生命周期重新被調用,兩個fragment便會重疊出錯。
原因是當activity被意外回收時會調用onSaveInstanceState()保持自身的一些狀态和資訊,以備在onCreate()方法中能夠直接擷取而不需要重新建立。
fragment的執行個體也會在onSaveInstanceState()中進行儲存,是以在onCreate()方法中等于建立了兩個Fragment的執行個體,當我控制一個fragment隐藏時,假設這個fragment的名字叫aFragment,由于現在activity實際上有兩個aFragment,而我隻隐藏了一個是以會導緻fragment重疊。
解決的辦法
既然原因是由于建立了兩次Fragment導緻的,那麼直覺的辦法當然是控制activity的onCreate()方法讓其隻建立一次Fragment。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
// 在頁面重新開機時,Fragment會被儲存恢複,而此時再加載Fragment會重複加載,導緻重疊 ;
if(saveInstanceState == null){
// 或者 if(findFragmentByTag(mFragmentTag) == null)
// 正常情況下去 加載根Fragment
}
}
通過判斷savedInstanceState是否為空可以知道這是第一次建立還是GC之後再次調用的onCreate(),隻在第一次onCreate()時建立aFragmen的執行個體,就可以避免重疊的問題。
還有一個辦法就是重寫activity的onSaveInstanceState()方法,去掉其中儲存fragment的代碼,缺點是當頁面比較複雜時,saveInstance除了儲存fragment的狀态還儲存了所有view的狀态,必須将view的狀态儲存寫一遍,是以推薦使用第一種方法。