fargment重疊問題解決

一、問題描述

相信大家在使用Fragment的過程中,肯定碰到過Fragment重疊的問題,重啓應用就好了。然而原因是什麼呢?

二、原因分析

首先,Android管理Fragment有兩種方式,使用add、hide、show的方式和replace方式,兩種方式各有優缺點。

  1. replace方式 
    如果使用這種方式,是可以避免重疊的問題,但是每次replace會把生命週期全部執行一遍,如果在這些生命週期函數 里拉取數據的話,就會不斷重複的加載刷新數據,所以我們並不推薦使用這種方式。

  2. add、hide、show的方式 
    雖然這種方式避免了可能重複加載刷新數據的問題,但是會出現重疊的問題。

原因:

當系統內存不足,Fragment 的宿主 Activity 回收的時候,Fragment 的實例並沒有隨之被回收。Activity 被系統回收時,會主動調用 onSaveInstance() 方法來保存視圖層(View Hierarchy),所以當 Activity 通過導航再次被重建時,之前被實例化過的 Fragment 依然會出現在 Activity 中,此時的 FragmentTransaction 中的相當於又再次 add 了 fragment 進去的,hide()和show()方法對之前保存的fragment已經失效了,所以就出現了重疊。 
然而我們還是推薦使用這個,我們可以解決。

三、問題重現

既然要解決問題,自然要重現一下! 
1.手機的 “設置” - “開發者選項” - 打開”不保留活動”(主要用於模擬Activity被及時回收) 
2.把 app 切換到後臺,再重新打開,通過點按不同的 tab 來切換 Fragment 
這裏寫圖片描述

四、解決方法

方法一、簡單暴力

通過註釋掉這句話,這樣主 Activity 因爲種種原因被回收的時候就不會保存之前的 fragment state

@Override
protectedvoidonSaveInstanceState(Bundle outState) {
//如果用以下這種做法則不保存狀態,再次進來的話會顯示默認tab
//總是執行這句代碼來調用父類去保存視圖層的狀態
//super.onSaveInstanceState(outState);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

方法二、(推薦使用)

重寫onAttachFragment,重新讓新的Fragment指向了原本未被銷燬的fragment,它就是onAttach方法對應的Fragment對象

    @Override
    public void onAttachFragment(Fragment fragment) {
        if (tab1 == null && fragment instanceof Tab1Fragment)
            tab1 = fragment;
        if (tab2 == null && fragment instanceof Tab2Fragment)
            tab2 = fragment;
        if (tab3 == null && fragment instanceof Tab3Fragment)
            tab3 = fragment;
        if (tab4 == null && fragment instanceof Tab4Fragment)
            tab4 = fragment;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

方法三

思路同樣是阻止系統恢復Fragment state,在FragmentActivity保存所有Fragment狀態前把Fragment從FragmentManager中移除掉。

    protected void onSaveInstanceState(Bundle outState) {
        FragmentTransaction transaction = fm.beginTransaction();
        transaction.remove(tab1);
        transaction.remove(tab2);
        transaction.remove(tab3);
        transaction.remove(tab4);
        transaction.commitAllowingStateLoss();
        super.onSaveInstanceState(outState);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章