前提:这次项目中采用了在fragment中添加了一个viewpager的形式,viewpager中切换的是fragment。
BUG:退出了那个包含viewpager的fragment并重新进入,切换viewpager时,不调用fragmentpageradapter适配器的getItem()方法,在显示上,出现viewpager的显示数量增多、显示数据不正确(这个情况只在初始化fragment时,需要传递参数的情况)的情况。
调试:fragmentpageradapter的instantiateItem(ViewGroup container, int position)方法,在调用的时候做了优化处理:
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
final long itemId = getItemId(position);
// Do we already have this fragment?
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
} else {
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
makeFragmentName(container.getId(), itemId));
}
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
解决:在实例化FragmentPagerAdapter类时,需要传递两个参数,将第一个参数设置为getChildFragmentManager()而非getFragmentManager()即可解决问题。
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()}.
*/
final public FragmentManager getFragmentManager() {
return mFragmentManager;
}
可以理解为:
getChildFragmentManager()是在fragment 里面子容器的碎片管理。