I figured out exactly what is going wrong. The FragmentStatePagerAdapter caches the fragments and saved states in ArrayLists: mFragments and mSavedState. But when the fragments are reordered, there is no mechanism for reordering the elements of mFragments and mSavedState. Therefore, the adapter will provide the wrong fragments to the pager.
Is http://code.google.com/p/android/ the appropriate place to file this issue? Here is my fix. I add a getItemId() function to FragmentStatePagerAdapter. (This mirrors the reordering implementation in FragmentPagerAdapter.) I store an array of the itemIds at all times. Then, in startUpdate(), I check if the itemIds array has changed. If it has, then I reorder mFragments and mSavedState accordingly. This fix is fairly inefficient because startUpdate() is called many times by ViewPager. Actually, we only need to perform the mItemIds/mFragments/mSavedState reordering when ViewPager.dataSetChanged() is called. But I wanted to avoid having to modify ViewPager as well. Note that these changes cannot be achieved by subclassing FragmentStatePagerAdapter because we need access to the private members mFragments and mSavedState. Here are my changes: public abstract class FragmentStatePagerAdapter extends PagerAdapter { private long[] mItemIds = new long[] {}; /** * Return a unique identifier for the item at the given position. */ public long getItemId(int position) { return position; } @Override public void startUpdate(ViewGroup container) { long[] newItemIds = new long[getCount()]; for (int i = 0; i < newItemIds.length; i++) { newItemIds[i] = getItemId(i); } if (!Arrays.equals(mItemIds, newItemIds)) { ArrayList<Fragment.SavedState> newSavedState = new ArrayList<Fragment.SavedState>(); ArrayList<Fragment> newFragments = new ArrayList<Fragment>(); for (int oldPosition = 0; oldPosition < mItemIds.length; oldPosition++) { int newPosition = POSITION_NONE; for (int i = 0; i < newItemIds.length; i++) { if (mItemIds[oldPosition] == newItemIds[i]) { newPosition = i; break; } } if (newPosition >= 0) { if (oldPosition < mSavedState.size()) { Fragment.SavedState savedState = mSavedState.get(oldPosition); if (savedState != null) { while (newSavedState.size() <= newPosition) { newSavedState.add(null); } newSavedState.set(newPosition, savedState); } } if (oldPosition < mFragments.size()) { Fragment fragment = mFragments.get(oldPosition); if (fragment != null) { while (newFragments.size() <= newPosition) { newFragments.add(null); } newFragments.set(newPosition, fragment); } } } } mItemIds = newItemIds; mSavedState = newSavedState; mFragments = newFragments; } } } -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

