title: ArrayList Index Out Of Bound exception in android custom list view adapter
body: <p>This is my below code , where my list looks like</p>
  
  <pre><code>position 1  |  image1      image2      image3
              ----------------------------------------
  position 2  |  image1      image2      image3
  </code></pre>
  
  <p>I mean dynamically adding my images according to number of items in list for eg if my list has 21 items , then mylist populate 3 images in each position and totally 7 position gets created. My code is working fine</p>
  
  <pre><code> public class ListViewAdapter extends BaseAdapter {
  private static final String TAG = "Book-shelf";
  private Activity activity;
  private int totalBooks = 0;
  private int bookItem = 0;
  private int numberOfBookRows = 0;
  private int extraBooks = 0;
  int layoutId;
  private int bookImage;
  private ArrayList&lt;HashMap&lt;String, String&gt;&gt; dataList;
  private static LayoutInflater inflater = null;
  
  public ListViewAdapter(Activity a, int listRow,
          ArrayList&lt;HashMap&lt;String, String&gt;&gt; fileList) {
      super();
  
      activity = a;
      dataList = fileList;
      layoutId = listRow;
      inflater = (LayoutInflater) activity
              .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  }
  
  @Override
  public int getCount() {
      // TODO Auto-generated method stub
      return dataList.size();
  }
  </code></pre>
  
  <p><strong>The modified one is for the above getCountmethod</strong></p>
  
  <pre><code>   @Override
  public Object getCount() {
      // TODO Auto-generated method stub
      return numberOfBookRows;
  }
  
  @Override
  public Object getItem(int position) {
      // TODO Auto-generated method stub
      return dataList.get(position);
  }
  
  
  @Override
  public long getItemId(int position) {
      // TODO Auto-generated method stub
      return position;
  }
  
  public void calculateRowsAndColms() {
      totalBooks = 0;
      bookItem = 0;
      numberOfBookRows = 0;
      extraBooks = 0;
  
      totalBooks = dataList.size();
      bookItem = 3;// TODO: make it dynamic
      if (totalBooks &lt; bookItem &amp;&amp; totalBooks &gt; 0) {
          numberOfBookRows = 1;
      } else {
          numberOfBookRows = (totalBooks / bookItem);
          extraBooks = (totalBooks % bookItem);
          if (extraBooks != 0)
              numberOfBookRows++;
      }
  
      Log.d(TAG, " Total books:" + totalBooks);
      Log.d(TAG, " Number of books to be displayed:" + bookItem);
      Log.d(TAG, " Number of rows occupying the books:" + numberOfBookRows);
      Log.d(TAG, " Number of extra books(odd count):" + extraBooks);
  }
  </code></pre>
  
  <p>This is my View code of arrayadapter</p>
  
  <pre><code> @Override
  public View getView(int position, View convertView, ViewGroup parent) {
  
      ViewHolder holder;
      View v = convertView;
      Log.d("View", "view" + v);
      calculateRowsAndColms();
      bookImage = R.drawable.book1;
      Log.d("Datalist","size="+dataList.size());
      if (convertView == null) {
          holder = new ViewHolder();
          v = inflater.inflate(layoutId, null, false);
  
          ImageView image1 = (ImageView) v.findViewById(R.id.image1);
          ImageView image2 = (ImageView) v.findViewById(R.id.image2);
          ImageView image3 = (ImageView) v.findViewById(R.id.image3);
  
          TextView t1 = (TextView) v.findViewById(R.id.textView1);
          TextView t2 = (TextView) v.findViewById(R.id.textView2);
          TextView t3 = (TextView) v.findViewById(R.id.textView3);
  
          holder.imgList.add(image1);
          holder.imgList.add(image2);
          holder.imgList.add(image3);
  
          holder.textList.add(t1);
          holder.textList.add(t2);
          holder.textList.add(t3);
  
          v.setTag(holder);
  
      } else {
          holder = (ViewHolder) v.getTag();
      }
      int k;
  
   if ((position == numberOfBookRows - 1) &amp;&amp; extraBooks != 0) {
  
  
                      for (int i = 0; i &lt; extraBooks; i++) {
                          Log.d("inside if", "position" + position);
                          Log.d("inside if", "numberofbookrows" + numberOfBookRows);
                          int k = (position * bookItem) + i;
                          holder.imgList.get(i).setBackgroundResource(bookImage);
                          holder.imgList.get(i).setOnClickListener(
                                  new OnBookClickListner());
                          holder.imgList.get(i).setVisibility(View.VISIBLE);
                          holder.imgList.get(i).setId(k);
                          holder.textList.get(i).setText(dataList.get(k).get("pdf"));
                          Log.d("if k value","k="+k+"value="+dataList.get(k).get("pdf"));
  
                      }
  
                  } else if((position &lt;= numberOfBookRows - 1) &amp;&amp; totalBooks&lt;bookItem)
                  {
  
                      for (int i = 0; i &lt; totalBooks; i++) {
  
                          Log.d("inside else", "position" + position);
                          Log.d("inside else", "numberofbookrows" + numberOfBookRows);
                          int k = (position * bookItem) + i;
                          holder.imgList.get(i).setBackgroundResource(bookImage);
                          holder.imgList.get(i).setOnClickListener(
                                  new OnBookClickListner());
                          holder.imgList.get(i).setVisibility(View.VISIBLE);
                          holder.imgList.get(i).setId(k);
                          holder.textList.get(i).setText(dataList.get(k).get("pdf"));
                          Log.d("2nd if k value","k="+k+"value="+dataList.get(k).get("pdf"));
  
                      }
                  }
                  else 
                  {
                      for (int i = 0; i &lt; bookItem; i++) {
                          int k = (position * bookItem) + i;
                          holder.imgList.get(i).setBackgroundResource(bookImage);
                          holder.imgList.get(i).setOnClickListener(
                                  new OnBookClickListner());
                          holder.imgList.get(i).setVisibility(View.VISIBLE);
                          holder.imgList.get(i).setId(k);
                          holder.textList.get(i).setText(dataList.get(k).get("pdf"));
                          Log.d("3rd if k value","k="+k+"value="+dataList.get(k).get("pdf"));
  
                      }
  
                  }
  
  return v;
  
  }
  
  static class ViewHolder {
      ArrayList&lt;ImageView&gt; imgList = new ArrayList&lt;ImageView&gt;();
      ArrayList&lt;TextView&gt; textList = new ArrayList&lt;TextView&gt;();
  
      // ImageView image1, image2 ,image3;
  }
  
  public class OnBookClickListner implements OnClickListener {
  
      @Override
      public void onClick(View v) {
          Log.d(TAG, " ITEM SELECTED IN LIST VIEW:" + v.getId());
          /*
           * Intent intent = new Intent(MainActivity.this,
           * MainActivity.class); startActivity(intent);
           */
      }
  
  }
  
  }
  </code></pre>
  
  <p>Now When i run this code , im getting my expected output, but when i try to scroll the list, the app get close and i get fatal exception </p>
  
  <pre><code>    07-22 03:57:26.501: E/AndroidRuntime(1314): FATAL EXCEPTION: main
  07-22 03:57:26.501: E/AndroidRuntime(1314): java.lang.IndexOutOfBoundsException: Invalid index 21, size is 20
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at java.util.ArrayList.get(ArrayList.java:308)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at com.example.samplebookshelfdesign.ListViewAdapter.getView(ListViewAdapter.java:151)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.widget.AbsListView.obtainView(AbsListView.java:2161)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.widget.ListView.makeAndAddView(ListView.java:1840)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.widget.ListView.fillDown(ListView.java:675)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.widget.ListView.fillGap(ListView.java:639)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4970)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3126)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.widget.AbsListView.onTouchEvent(AbsListView.java:3400)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.View.dispatchTouchEvent(View.java:7384)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2203)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1938)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1952)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1952)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1952)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1952)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1966)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1418)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.app.Activity.dispatchTouchEvent(Activity.java:2424)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1914)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.View.dispatchPointerEvent(View.java:7564)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3883)
  07-22 03:57:26.501: E/AndroidRuntime(1314):     at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3778)
  </code></pre>