前言
前段時間在工作中遇到了fragment的重疊問題硕噩,耽誤了挺久的舶沛,主要原因還是在于自己對fragment的研究還不夠深入罩抗,只是一些泛泛的了解求摇。
重疊問題出現(xiàn)的原因
當我使用show和hide來控制fragment的顯隱時窍荧,一旦作為容器的activity被系統(tǒng)GC辉巡,導致activity的所有生命周期重新被調(diào)用,兩個fragment便會重疊出錯搅荞。
原因是當activity被意外回收時會調(diào)用onSaveInstanceState()保持自身的一些狀態(tài)和信息红氯,以備在onCreate()方法中能夠直接獲取而不需要重新創(chuàng)建框咙。
fragment的實例也會在onSaveInstanceState()中進行保存,所以在onCreate()方法中等于創(chuàng)建了兩個Fragment的實例痢甘,當我控制一個fragment隱藏時喇嘱,假設這個fragment的名字叫aFragment,由于現(xiàn)在activity實際上有兩個aFragment塞栅,而我只隱藏了一個所以會導致fragment重疊。
解決的辦法
既然原因是由于創(chuàng)建了兩次Fragment導致的放椰,那么直覺的辦法當然是控制activity的onCreate()方法讓其只創(chuàng)建一次Fragment作烟。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
// 在頁面重啟時,F(xiàn)ragment會被保存恢復砾医,而此時再加載Fragment會重復加載错邦,導致重疊 ;
if(saveInstanceState == null){
// 或者 if(findFragmentByTag(mFragmentTag) == null)
// 正常情況下去 加載根Fragment
}
}
通過判斷savedInstanceState是否為空可以知道這是第一次創(chuàng)建還是GC之后再次調(diào)用的onCreate(),只在第一次onCreate()時創(chuàng)建aFragmen的實例魂拦,就可以避免重疊的問題借尿。
還有一個辦法就是重寫activity的onSaveInstanceState()方法,去掉其中保存fragment的代碼茂契,缺點是當頁面比較復雜時战秋,saveInstance除了保存fragment的狀態(tài)還保存了所有view的狀態(tài),必須將view的狀態(tài)保存寫一遍濒生,所以推薦使用第一種方法。