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