Android Fragment嵌套Fragment使用ViewPager时不显示

问题

如下图,父Fragment嵌套子Fragment在切换过程中部分子Fragment不显示。

这里写图片描述

解决方案

原来的子Fragment中FragmentPagerAdapter的初始化使用的是getFragmentManager()

   ...
   new FragmentPagerAdapter(getFragmentManager())
   ...

百度解决方案后得知:把getFragmentManager()换成getChildFragmentManager()即可。
修改后的代码:

...
new FragmentPagerAdapter(getChildFragmentManager()) 
...

确实解决的我的问题。

源码分析

getSupportFragmentManager()

 /**
     * Return the FragmentManager for interacting with fragments associated
     * with this activity.
     */
    public FragmentManager getSupportFragmentManager() {
        return mFragments.getSupportFragmentManager();
    }

注释说的很清楚,当fragment与Activity有关联时使用。即在Activity创建父Fragment中使用。

getFragmentManager()

/**
     * Return the FragmentManager for interacting with fragments associated
     * with this fragment's activity.  Note that this will be non-null slightly
     * before {@link #getActivity()}, during the time from when the fragment is
     * placed in a {@link FragmentTransaction} until it is committed and
     * attached to its activity.
     *
     * <p>If this Fragment is a child of another Fragment, the FragmentManager
     * returned here will be the parent's {@link #getChildFragmentManager()}.
     *
     * @see #requireFragmentManager()
     */
    @Nullable
    final public FragmentManager getFragmentManager() {
        return mFragmentManager;
    }

注释很多,但是最后一句话很关键。我就不解释了。

getChildFragmentManager()

/**
     * Return a private FragmentManager for placing and managing Fragments
     * inside of this Fragment.
     */
    @NonNull
    final public FragmentManager getChildFragmentManager() {
        if (mChildFragmentManager == null) {
            instantiateChildFragmentManager();
            if (mState >= RESUMED) {
                mChildFragmentManager.dispatchResume();
            } else if (mState >= STARTED) {
                mChildFragmentManager.dispatchStart();
            } else if (mState >= ACTIVITY_CREATED) {
                mChildFragmentManager.dispatchActivityCreated();
            } else if (mState >= CREATED) {
                mChildFragmentManager.dispatchCreate();
            }
        }
        return mChildFragmentManager;
    }

直接说明白自己是在Fragment中管理Fragments的。

分析

  1. 由于父Fragment是嵌套在Activity中的,而Activty除非不显示,否则是不会被销毁的,即getSupportFragmentManager()会一直存在,在父Fragemnt中显示一般会很稳定正常。
  2. 由于在子Fragment中getFragmentManager()返回的父Fragment的FragmentManager,所以一旦父Fragment在切换的过程中被销毁,则FragmentManager丢失,造成子Fragment显示错误。
  3. 而getChildFragmentManager()会判断Fragment的状态,对FragmentManager进行保存,则不会出现上面的问题。

参考

https://blog.csdn.net/qq_29967217/article/details/76836816

https://blog.csdn.net/qq_29967217/article/details/76836816

猜你喜欢

转载自blog.csdn.net/demonliuhui/article/details/80841416