天天看點

Fragment重疊的問題

最近幾天在寫多個fragment頁面,碰到了一個老生常談,也是非常常見的問題,那就是fragment重疊的問題,我相信這個問題隻要是Android的猿人都會碰到,确實是太常見了,解決起來也是非常簡單的,我看了看很多部落格,用的最多的解決辦法是給fragment加個背景顔色,因為fragment預設的背景色是透明的,這樣确實能解決重疊的問題,但是隻允許在特定的布局下,局限于布局特别的簡單,一旦布局複雜了,這樣的解決辦法是無用的,因為我就碰到過。。。。

一、首先重疊是怎麼出現的?

Android管理Fragment的方式主要有兩種,這兩種各自都有自己的特點:

(1)使用replace來替代,這種方式可以避免重疊的問題,但是每次replace的時候都會重新執行生命周期,當大量擷取資料的時候,就會不斷的重複加載資料,這顯然不是我們需要的使用的方式;

(2)使用add、show、hide方式來管理,這種方式可以避免重複加載資料,但是會導緻今天的重點——重疊;

那麼出現重疊的原因是什麼呢?咱們就得從fragment的特性說起了,fragment是一個小型的activity,基本上是依附在activity上的,是以,當系統記憶體不足,Fragment 的宿主 Activity 回收的時候,Fragment 的執行個體并沒有随之被回收。Activity 被系統回收時,會主動調用 onSaveInstance() 方法來儲存視圖層(View Hierarchy),是以當 Activity 通過導航再次被重建時,之前被執行個體化過的 Fragment 依然會出現在 Activity 中,此時FragmentTransaction 中的相當于又再次 add 了 fragment 進去的,hide()和show()方法對之前儲存的fragment已經失效了,是以就出現了重疊。

是以、正應了那句話,萬物皆對象,但沒有一個對象是十全十美的東西,各有優缺點。

二、解決方案:

出現重疊的解決方案有四種:

(1)視覺沖擊:将fragment的背景顔色設定成非透明的,因為fragment預設的背景色是透明的,是以,這可以解決透明的問題,但是這隻是給使用者的體驗感覺,但實際上重疊問題依然存在。

(2)簡單粗暴:上面說了導緻重疊的原因是Activity被系統回收時,會主動調用onSaveInstance(),通過觀察,在onSaveInstance()方法内首先會去調用super,是以,問題就很明朗了,既然他會去儲存目前的狀态,那麼咱們重寫onSaveInstance()方法,不讓其執行super,重疊問題不就解決了嘛,果然是這樣的。

Fragment重疊的問題

(3)重寫onAttachFragment()方法,讓新的Fragment指向未被銷毀的Fragment;

@Override
    public void onAttachFragment(Fragment fragment) {
        if (fragment1 == null && fragment instanceof Fragment1)
            fragment1 = fragment;
        if (fragment2  == null && fragment instanceof Fragment2)
            fragment2  = fragment;
        if (fragment3  == null && fragment instanceof Fragment3)
            fragment3  = fragment;
        if (fragment4  == null && fragment instanceof Fragment4)
            fragment4  = fragment;
    }
           

(4)其實此方法與第二種方法差不太多,無非就是多幾行代碼,思路都一樣,就是不讓其恢複到原來的fragment state,在儲存fragment state之前把FragmentManager内的fragment都移除掉。

protected void onSaveInstanceState(Bundle outState) {
        FragmentTransaction transaction = fm.beginTransaction();
        transaction.remove(fragment1);
        transaction.remove(fragment2);
        transaction.remove(fragment3);
        transaction.remove(fragment4);
        transaction.commitAllowingStateLoss();
        super.onSaveInstanceState(outState);
    }
           

以上是我總結的四種解決fragment重疊問題的方法,希望對大家有幫助。

繼續閱讀