Fragment銷毀時replace和add兩個方法的區別


這個首先從一個bug說起,如圖:

 

我們都知道fragment切換有兩種方式:

1. replace方式

transaction.replace(R.id.content, IndexFragment);

2. add-hide-show方式

transaction.add(R.id.content, IndexFragment);  transaction.hide(otherfragment);  transaction.show(thisfragment);

而上面按鈕中出現bug的就是采用第二種方式。然后我們來分析下用add,hide,show為什么出現這種bug,我把每個操作都打印出了以下日志:

復現bug的操作是:
1.首先打開,默認選中的是第一個tab,如上面的一張圖片正常那樣。
2.切換到tab2,並把tab1 hide掉;
3.再切回到tab1,並不會觸發tab1對應fragment的任何生命周期;
4.然后home鍵進入后台,我在activity的onPause()中手動對IndexFragment賦空,模擬長時間后台,系統銷毀了該引用。

IndexFragment=null;

5.再次啟動,其實tab1 的fragment實例在內存中還在,只是他的引用被銷毀了。
6.再切到tab2,這里其實是先把tab1的hide,在show tab2,但是tab1 的fragment引用為空,所以無法hide,就出現了tab2疊在tab1上的花屏情況。
7.再切到tab1,tab1就會重復創建對象。

同樣的操作,我們使用replace的方式

使用replace方式,雖然這種方式會避免上述的bug,但也是重復創建了對象。因為replace方式,對應的FrameLayout只有一 層,而add方式,這個FrameLayout其實有2層。但是這種方式的缺點是:每次replace會把生命周期全部執行一遍,如果在這些生命周期函數 里拉取數據的話,就會不斷重復的加載刷新數據。

那么最合適的處理方式是這樣的:

1.在add的時候,加上一個tab參數
transaction.add(R.id.content, IndexFragment,”Tab1″);
2.然后當IndexFragment引用被回收置空的話,先通過
IndexFragment=FragmentManager.findFragmentByTag(“Tab1″);
找到對應的引用,然后繼續上面的hide,show;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM