问题
如下图,父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的。
分析
由于父Fragment是嵌套在Activity中的,而Activty除非不显示,否则是不会被销毁的,即getSupportFragmentManager()会一直存在,在父Fragemnt中显示一般会很稳定正常。由于在子Fragment中getFragmentManager()返回的父Fragment的FragmentManager,所以一旦父Fragment在切换的过程中被销毁,则FragmentManager丢失,造成子Fragment显示错误。而getChildFragmentManager()会判断Fragment的状态,对FragmentManager进行保存,则不会出现上面的问题。
参考
https://blog.csdn.net/qq_29967217/article/details/76836816
https://blog.csdn.net/qq_29967217/article/details/76836816