1. 程式人生 > >兩層fragment嵌套時出現空白,(收藏別人的)

兩層fragment嵌套時出現空白,(收藏別人的)

在屏幕上 比較 adding back markdown solid ring limit 好的

完美解決 兩層Fragment,內層空白

轉載:http://blog.csdn.net/bingospunky/article/details/51352400

目錄(?)[+]

前言

兩層Fragment在某些情況下,內層Fragment會顯示空白,這是一個比較常見的問題,以前我也有一些解法,這次又遇到了這個問題,索性看了一下Fragment相關的源碼,找到了問題的根源。

如果你想看一下什麽樣的代碼會出現Fragment出現空白,這個demo會告訴你。

之前寫過一篇文章兩層Fragment嵌套,外層Fragment切換時內層Fragment不顯示內容,是兩層Fragment,外層使用replace切換,內層是ViewPager切換,內層的Fragment在某些情況下會不顯示。現在來看這和兩層ViewPager是一個原因的。

解法

解法有很多,這裏先寫兩種可行的解法,下面章節會解釋產生空白Fragment的根本原因,當你知其所以然的時候,就可以有n種解法了。

  • 通過ViewPager.setOffscreenPageLimit(3);設置ViewPager離屏的Page很大。
  • 修改包含內層Fragment的外層Fragment的onCreateView方法成下面這個樣子
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if(rootView == null){
            rootView = inflater.inflate(R.layout.fragment3, null);
            // 初始化View,添加Fragment
            // ... 
        }
        return rootView;
    }

原因剖析

產生空白的根本原因是往ViewGroup裏添加子View失敗。

概念

要解釋明白這個過程首先需要明確幾個概念,不知道各位看官是否明確,我先在這裏列出來:

  • Fragment有一個叫mView的屬性,就是這個Fragment對應的View,歸根結底來說,Fragment就是代表一個View,FragmentManager操作Fragment就是操作Fragment所包含的View的添加、刪除等,只是在他上面加了一些類似生命周期的控制。
  • FragmentManager這個類是管理Fragment的類,比如添加Fragment就是這個類來實現的,它添加一個Fragment的時候回讓一個字符串與一個Fragment,如果這個字符串存在,就不會再添加這個Fragment。
  • FragmentManager這個類是與Actiity相關的,就是 * 一個FragmentAativity *,這一點很重要。
  • 如果Fragment結合ViewPager使用,那麽Fragment是被Adapter調用FragmentManager添加的,與Fragment對應的字符串是在Adapter裏決定的,有Fragment類名相關的一個字符串。

約定

下面我們做如下約定:一個Activity通過一個ViewPager包含4個Fragment,分別命名為mFragment1,mFragment2,mFragment3,mFragment4,其中mFragment3通過ViewPager包含3個Fragment,分別命名為mFragment31,mFragment32,mFragment33。

操作:

  • 1、顯示mFragment1
  • 2、顯示mFragment3
  • 3、顯示mFragment1
  • 4、顯示mFragment3
    在第4步的時候,內層的Fragment就會不顯示。

解釋

  • 執行完第2步:mFragment3的onCreateView返回的View顯示在屏幕上,裏面添加了幾個子View,子View就是Fragment對應的View,而且這幾個子View是通過FragmentManager添加的,有String與之對應。
  • 執行完第3步:mFragment3的onDestroyView方法會執行,代表著mView將被廢棄,下次會通過onCreateView創建一個新的mView。在FragmentManager裏mFragment32對應的字符串還存在,因為我們都知道FragmentPagerAdapter裏的destroyItem沒有被執行,至於destroyItem方法什麽時候被執行你應該懂的。
  • 執行完第4步:mFragment3的onCreateView方法被執行,返回的rootView顯示在界面上,然後我們的代碼裏會通過FragmentPagerAdapter給這個rootView添加Fragment,也就是給這個rootView添加子View。在我們添加Fragment的過程中,因為在前面的過程中mFragment32對應的字符串已經存在了,所以添加mFragment32是失敗的,即給rootView添加子View失敗,所以界面裏顯示的就是空白。

總結

歸根結底看是由於一些Fragment相關的原因導致往ViewGroup裏添加子View失敗。至於解法就可以有很多了,比較而言,我覺得前文提到的兩種解法是比較好的,如果內存不緊張的情況下推薦用解法1;內存比較緊張的情況下,建議采用解法2

兩層fragment嵌套時出現空白,(收藏別人的)