I believe that FragmentStatePagerAdapter does not behave correctly when 
overriding getItemPosition(Object object) with the purpose of reordering 
the pages.

Below is a simple example. In the initial state, the order of the pages is 
{A, B, C}. Upon calling toggleState(), the order of the pages changes to 
{A, C, B}. By overriding getItemPosition(Object object), we ensure that the 
current page being viewed (A, B, or C) does not change.

public static class TestPagerAdapter extends FragmentStatePagerAdapter {
private boolean mState = true;
 public TestPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
 @Override
public int getCount() {
return 3;
}
 private void toggleState() {
mState = !mState;
notifyDataSetChanged();
}
 private String getLabel(int position) {
switch (position) {
case 0:
return "A";
case 1:
return mState ? "B" : "C";
default:
return mState ? "C" : "B";
}
}
 @Override
public int getItemPosition(Object object) {
String label = ((TestFragment) object).getLabel();
if (label.equals("A")) {
return 0;
} else if (label.equals("B")) {
return mState ? 1 : 2;
} else {
return mState ? 2 : 1;
}
}
 @Override
public CharSequence getPageTitle(int position) {
return getLabel(position);
}
 @Override
public Fragment getItem(int position) {
return TestFragment.newInstance(getLabel(position));
}
}


I have encountered two separate behaviours which seem incorrect.

   1. If I immediately call toggleState() (while viewing page A, before 
   swiping to any other page), the app crashes.
   
   java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
     at 
   java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
     at java.util.ArrayList.set(ArrayList.java:477)
     at 
   
android.support.v4.app.FragmentStatePagerAdapter.destroyItem(FragmentStatePagerAdapter.java:136)
     at android.support.v4.view.ViewPager.populate(ViewPager.java:867)
     at 
   android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:469)
     at 
   android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:441)
     at android.support.v4.view.ViewPager.dataSetChanged(ViewPager.java:766)
     at 
   
android.support.v4.view.ViewPager$PagerObserver.onChanged(ViewPager.java:2519)
     at 
   android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
     at 
   
android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:276)
     at 
   
com.ugglynoodle.test.testfragmentstatepageradapter.MainActivity$TestPagerAdapter.toggleState(MainActivity.java:55)
     ...
   
   Looking at the source (FragmentStatePagerAdapter.java), this would be 
   fixed by first checking the size of mFragments (as in lines 113-115) before 
   calling set() in line 136.
   
   2. If I first swipe to page B, then getItem(2) is called, page C is 
   created, and mFragments now has a size of 3 (this will prevent the crash 
   above from happening in a moment). Then I swipe back to page A, and page C 
   is destroyed, as it should be (since it is 2 pages away, and I'm using the 
   default offscreen page limit of 1). Now, I call toggleState(). Page B is 
   now destroyed. However, page C is NOT recreated! This means, when I now 
   swipe to the right, I get an empty page.
   
First, it would be nice to know whether I'm correct and these are in fact 
bugs, or whether I'm doing something wrong. If they are bugs, can anyone 
suggest a workaround (other than debugging and rebuilding the support 
library myself)? Surely somebody must have overridden 
getItemPosition(Object object) successfully (apart from setting everything 
to POSITION_NONE)?

I am using the current revision (10) of the support library.

(Apologies if you have seen this post multiple times. My original post 
never showed up in the Google Group for me, so I am trying to post it 
again.)

-- 
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

Reply via email to