title: Android ViewPager throwing IndexOutOfBounds exception when setting current item/page
body: <p>I have a ViewPager with three items. I am trying to set the ViewPager to view the page furthest to the right (which would be the 2nd element). This is returning an IndexOutOfBounds exception, though I know the index ought to be in bounds. Here is the exact stack:</p>
  
  <pre><code>02-22 12:22:50.256: E/AndroidRuntime(384): FATAL EXCEPTION: main
  02-22 12:22:50.256: E/AndroidRuntime(384): java.lang.IndexOutOfBoundsException: index=1 count=0
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewGroup.addInArray(ViewGroup.java:2050)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewGroup.addViewInner(ViewGroup.java:1994)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewGroup.addViewInLayout(ViewGroup.java:1958)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewGroup.addViewInLayout(ViewGroup.java:1939)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.support.v4.view.ViewPager.addView(ViewPager.java:917)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewGroup.addView(ViewGroup.java:1828)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at us.tagverse.pagertest.MasterActivity$PAdapter.instantiateItem(MasterActivity.java:518)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.support.v4.view.PagerAdapter.instantiateItem(PagerAdapter.java:110)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:649)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.support.v4.view.ViewPager.populate(ViewPager.java:783)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1016)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.View.measure(View.java:8313)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.View.measure(View.java:8313)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.View.measure(View.java:8313)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.View.measure(View.java:8313)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewRoot.performTraversals(ViewRoot.java:839)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.os.Handler.dispatchMessage(Handler.java:99)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.os.Looper.loop(Looper.java:123)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at android.app.ActivityThread.main(ActivityThread.java:3683)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at java.lang.reflect.Method.invokeNative(Native Method)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at java.lang.reflect.Method.invoke(Method.java:507)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
  02-22 12:22:50.256: E/AndroidRuntime(384):  at dalvik.system.NativeStart.main(Native Method)
  </code></pre>
  
  <p>Note that the cause is <code>java.lang.IndexOutOfBoundsException: index=1 count=0</code>. This would imply that the count of the pages/items is 0 and the index I am requesting is 1. Neither of these things are true. Here is how I am calling my ViewPager and requesting the given page:</p>
  
  <pre><code>ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
  PAdapter adapter = new PAdapter();
  pager.setAdapter(adapter);
  pager.setCurrentItem(2);
  </code></pre>
  
  <p>Note that this call does not give any error, and correctly sets the current item to the middle item (index 1):</p>
  
  <pre><code>ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
  PAdapter adapter = new PAdapter();
  pager.setAdapter(adapter);
  pager.setCurrentItem(1);
  </code></pre>
  
  <p>I have a count of 3 items in the view pager. Here is my full PAdapter class, which extends the PagerAdapter class:</p>
  
  <pre><code>private class PAdapter extends PagerAdapter implements TitleProvider {
  
      private int COUNT = 3;
  
      private static final int SETTINGS_ACTIVITY = 0;
      private static final int MAIN_ACTIVITY = 1;
      private static final int FRIEND_LIST_ACTIVITY = 2;
  
      @Override
      public int getCount() {
          return COUNT;
      }
  
      @Override
      public Object instantiateItem(View collection, int position) {
          LinearLayout layout = new LinearLayout(getApplicationContext());
          LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          switch(position) {
          case MAIN_ACTIVITY :
              layout = (LinearLayout) inflater.inflate(R.layout.main, null, false);
              initMainLayout(layout);
              break;
          case SETTINGS_ACTIVITY :
              layout = (LinearLayout) inflater.inflate(R.layout.settings, null, false);
              initSettingsLayout(layout);
              break;
          case FRIEND_LIST_ACTIVITY :
              layout = (LinearLayout) inflater.inflate(R.layout.friend_list, null, false);
              initFriendListLayout(layout);
              break;
          }
          ((ViewPager)collection).addView(layout, position);
          return layout;
      }
  
      @Override
      public void destroyItem(View collection, int position, Object view) {
          ((ViewPager)collection).removeView((LinearLayout)view);
      }
  
      @Override
      public boolean isViewFromObject(View v, Object o) {
          return v == (LinearLayout)o;
      }
  
      @Override
      public void finishUpdate(View arg0) {
          //no need
      }
  
      @Override
      public void restoreState(Parcelable arg0, ClassLoader arg1) {
          //no need
      }
  
      @Override
      public Parcelable saveState() {
          return null;
      }
  
      @Override
      public void startUpdate(View arg0) {
          //no need
      }
  
      @Override
      public String getTitle(int position) {
          Resources res = getApplicationContext().getResources();
          switch(position) {
          case MAIN_ACTIVITY :
              return res.getString(R.string.app_name);
          case SETTINGS_ACTIVITY :
              return res.getString(R.string.settings);
          case FRIEND_LIST_ACTIVITY :
              return res.getString(R.string.friend_list);
          default :
              return null;
          }
      }
  }
  </code></pre>
  
  <p>The line <code>((ViewPager)collection).addView(layout, position);</code> causes the crash.</p>
  
  <p>As you can see, three items. Using setCurrentItem() with a parameter of 0 or 1 works just fine, but 2 causes this strange error. I've run out of ideas to solve it... unfortunately ViewPager resides in some uncharted waters of Android it seems. If anyone has some insight on how to solve this it would be much appreciated. Thanks!</p>
  
  <p>EDIT: As per Shereef's suggestion, I tried logging the child count via collection.getChildCount() and got the following result:</p>
  
  <pre><code>02-22 15:20:42.274: E/children count(645): count: 0
  02-22 15:20:42.454: E/children count(645): count: 1
  02-22 15:20:42.594: E/children count(645): count: 2
  </code></pre>
  
  <p>This is interesting. What this tells me is that its creating an empty PagerAdapter and adding them one at a time. <code>instantiateItem()</code> is called 3 times for the three visible views (center, left, and right). So I added this block of code inside the <code>instantiateItem()</code> method:</p>
  
  <pre><code>if(((ViewPager)collection).getChildCount() ==  2) {
      ((ViewPager)collection).setCurrentItem(2);
  }
  </code></pre>
  
  <p>So only if the count is established to be 2 will it set the page to 2 (this is a hacky solution which doesn't fully address the problem, but was worth a try). I got a similar error stack which pointed first to the line: <code>((ViewPager)collection).setCurrentItem(2);</code>, then <code>((ViewPager)collection).addView(layout, position);</code>.</p>
  
  <p>Hope this helps give some insight.</p>