前提:這次項目中採用了在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 裏面子容器的碎片管理。