本文出處:http://blog.csdn.net/twilight041132/article/details/43812745
?
在用Fragment做Tab頁面,發現有時候進入應用會同時顯示多個Tab內容,UI發生重疊。
當應用被強行關閉后(通過手機管家軟件手動強關,或系統為節省內存自動關閉應用),再次進入應用時,每次都有這現象。
第一次進入應用時,根據選擇的tab分別創建對應的Fragment,之后每次選擇頁面時隱藏其他tab內容。
通過分析發現,正常back鍵退出應用時,Activity及Fragment對象會被銷毀,因此再次進入時會在切換到Tab時創建對應的Fragment對象。
但是當強行關閉應用后,Activity雖然被回收,但Fragment對象仍然保持,再次進入應用時,系統會分別調用Fragment的onAttach方法將其附加到Activity上,
02-08 12:41:24.107: D/FragmentTab1(7032): onAttach
02-08 12:41:24.107: D/FragmentTab3(7032): onAttach
這里對應的就是強行關閉應用前的fragment對象,
后面會分別調用兩個fragment的onCreateView方法,因此這兩個Fragment對應的View層次結構都會加到Activity的View層次中。
雖然setSelection方法會把所有fragment先隱藏再顯示選中的對象,但由于此時Activity中Fragment對象的成員變量還未初始化,因此會再次實例化fragment對象,
之后add、show及hide的都是在第二次創建的對象上操作的,而之前被保持的fragment對象的視圖層次已經反映到Activity視圖中并且不會被hide,因此發生了上述重疊現象。
?
解決方法:
在Activity的onAttachFragment方法中,有一個fragment參數,它就是onAttach方法對應的Fragment對象,
通過判斷這個fragment對象,如果屬于我們的FragmentTabX類并且該類還未被實例化過,則將Activity的成員變量mFragmentTabX指向該fragment對象,這樣就可以在原來的fragment對象上操作add/show/hide,因此不會有重疊現象。
@Override public void onAttachFragment(Fragment fragment) { // TODO Auto-generated method stub super.onAttachFragment(fragment); Log.d(TAG,"onAttachFragment"); //mTab1,mTab2,mTab3 是在Activity中創建的Fragmentif (mTab1 == null && fragment instanceof FragmentTab1) { mTab1 = (FragmentTab1)fragment; }else if (mTab2 == null && fragment instanceof FragmentTab2) { mTab2 = (FragmentTab2)fragment; }else if (mTab3 == null && fragment instanceof FragmentTab3) { mTab3 = (FragmentTab3)fragment; } }
?
?
-------------------------------------華麗的分割線------------------------------------------
以下參考:http://m.blog.csdn.net/article/details?id=41912445
上面的貌似說的很有道理,但是測試了一下還是不行,也許是我遇到的問題跟他說的不一致。
我遇到的問題是:當報錯時(比如空指針)主頁面出現Fragment重疊。
在debug的時候,發現CarFragment是執行了onCreateView()的,意味著成功生成了車輛管理的界面,但究竟為什么仍然顯示的是SupplyFragment的界面呢,直觀感覺,SupplyFragment像一層蒙板一樣放在最上層,點擊其他4個tab欄,生成的Fragment都被隱藏在了它的下面。
后來在google查到相關資料,原因是:當Fragment長久不使用,系統進行回收,FragmentActivity調用onSaveInstanceState保存Fragment對象。很長時間后,再次打開app,系統恢復保存的Fragment,但是在FragmentActivity重新執行生命周期的時候,我們重新生成了fragment對象附加到該FragmentActivity,系統恢復的fragment和FragmentActivity失去關聯,進而出錯。
解決方案為以下兩種:
方法1:在fragmentActivity里oncreate方法判斷savedInstanceState==null才生成新Fragment,否則不做處理。
方法2:在fragmentActivity里重寫onSaveInstanceState方法,但不做實現,也就是將super.onSaveInstanceState(outState)注釋掉。
方法2很好理解,當系統要回收Fragment時,我們告訴系統:不要再保存Fragment。相當于用戶回到app的時候,我們就當用戶是第一次打開app(因為很長時間沒有操作了)。
方法1理論上沒有問題,但在測試的時候,用了一種非常規的方案,橫豎屏切換來測試,而在橫豎屏切換時,系統會首先銷毀FragmentActivity再重新生成,無法模擬測試條件,還要再研究。
方法1博主親測,沒有什么卵用。