title: reorder pages in FragmentStatePagerAdapter using getItemPosition(Object object)
body: <p>I believe that FragmentStatePagerAdapter does not behave correctly when overriding <code>getItemPosition(Object object)</code> with the purpose of reordering the pages.</p>
  
  <p>Below is a simple example. In the initial state, the order of the pages is {A, B, C}. Upon calling <code>toggleState()</code>, the order of the pages changes to {A, C, B}. By overriding <code>getItemPosition(Object object)</code>, we ensure that the current page being viewed (A, B, or C) does not change.</p>
  
  <pre><code>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));
      }
  }
  </code></pre>
  
  <p>I have encountered two separate behaviours which seem incorrect.</p>
  
  <ol>
  <li><p>If I immediately call <code>toggleState()</code> (while viewing page A, before swiping to any other page), the app crashes.</p>
  
  <pre><code>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)
    ...
  </code></pre>
  
  <p>Looking at the source of <code>FragmentStatePagerAdapter</code>, this would be fixed by first checking the size of <code>mFragments</code> (as in lines 113-115) before calling <code>set()</code> in line 136.</p></li>
  <li><p>If I first swipe to page B, then <code>getItem(2)</code> is called, page C is created, and <code>mFragments</code> 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 <code>toggleState()</code>. 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.</p></li>
  </ol>
  
  <p>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 <code>getItemPosition(Object object)</code> successfully (apart from setting everything to <code>POSITION_NONE</code>)?</p>
  
  <p>I am using the current revision (10) of the support library.</p>