兩層Fragment嵌套,外層Fragment切換時內層Fragment不顯示內容

前言

兩層Fragment在某些情況下,內層Fragment會顯示空白,這是一個比較常見的問題,百度到的一些帖子的方法有幾種,但是在即的項目中,只有下面這種起了作用。最後附上在一篇帖子上看到的出現這種情況的原因(反正我看不懂)。

解法

Activity中使用replace切換:

private void initFirstFragment() {
        course_fragment = new Fragment_main_course();    //雙層Fragment的第一層,自定義的Fragment
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.course_main, course_fragment);
        transaction.commit();
}

第一層Fragment添加:

private void initView(View view) {
        tabLayout = view.findViewById(R.id.course_tab);    //TabLayout
        viewPager = view.findViewById(R.id.course_view_pager);    //ViewPager
        fragmentList = new ArrayList<>();

        Fragment fragment_my_course = new Fragment_my_course();
        Fragment fragment_all_course = new Fragment_all_course();
        fragmentList.add(fragment_my_course);
        fragmentList.add(fragment_all_course);

        //重點就是下面這句話,一定要使用getChildFragmentManager()
        adapter = new MyAdapter(getChildFragmentManager());    //自定義的適配器
        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager);
}

下面的原因分析來源於:https://blog.csdn.net/bingospunky/article/details/51352400

原因剖析

產生空白的根本原因是往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失敗,所以界面裏顯示的就是空白。

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