title: What sets the maximum position value when getView is called? (Shrinking a ListView)
body: <p>I'm displaying a ListView and at first it works just fine - everything displays and scrolls OK.   There are 12 items in the ListView.      Then I try to reduce the number of items in the ListView, so I reduce the size of dataset and it crashes in the adapter's <em>getView()</em> because <em>getView()</em> is called with a position value too big for the new, smaller list, resulting in an array index out of bounds.</p>
  
  <p><strong>Source Snippets:</strong></p>
  
  <p>In <em>onCreate()</em> I attach my listview to the XML</p>
  
  <pre><code>   setContentView(R.layout.mylist);
     lv = getListView();
  </code></pre>
  
  <p>I create the adapter and bind it . . .</p>
  
  <pre><code>mylistadapter = new MyListAdapter(MyListActivity.this);
  setListAdapter(mylistadapter);   // bind the adapter
  </code></pre>
  
  <p>...the data source is an ArrayList called listItems. The first time around it has 12 items in it; later I clear it and add in 6 items.   </p>
  
  <pre><code>public static ArrayList&lt;String&gt;listItems=new ArrayList&lt;String&gt;();
  </code></pre>
  
  <p>After I clear it and add the 6 new items I call <em>notifyDataSetChanged()</em>.  </p>
  
  <p>In my adapter, which is a BaseAdapter, my override of <em>getCount()</em> looks like this. After shrinking listItems to 6 it correctly returns 6.</p>
  
  <pre><code>@Override
  public int getCount() {
      return listItems.size();
  }
  </code></pre>
  
  <p>To verify <em>notifyDataSetChanged()</em> was getting called I wrote an overrride of it to do logging and to prove to myself that it was really getting called.   With or without this override the behavior is the same.</p>
  
  <pre><code>// just overriding notifyDataSetChanged() to instrument it
  @Override
  public void notifyDataSetChanged() 
  {
      Log.e ("notifyDataSetChanged()...",   "listItems.size()=" + String.valueOf(listItems.size()) + "  lv.getCount()=" + String.valueOf(lv.getCount()) );   //!! debugging
      super.notifyDataSetChanged();
  }   
  </code></pre>
  
  <p>The <em>getView()</em> looks like this.  It blows up at the BOOM comment because position is 6 and listItems only has 6 items ([0]-[5]</p>
  
  <pre><code>@Override
      public View getView(int position, View convertView, ViewGroup parent) {
      ViewHolder holder;
      boolean select;
  
          Log.e ("getView() ...  " , "position=" + String.valueOf(position) + 
                     " AdapterCount=" + String.valueOf(getCount()) + "..." );   //!! debugging            
          if (convertView == null) {      
              LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              convertView = vi.inflate(R.layout.mylistitem, null);
              //This is still needed even though we point to an XML description
              convertView.setLayoutParams(new ListView.LayoutParams(
                      ListView.LayoutParams.MATCH_PARENT,
                      ListView.LayoutParams.MATCH_PARENT));
              holder = new ViewHolder();
  
              convertView.setTag(holder);
              holder.cV1.setTag(holder);  //These views need tags for onClick()
          }
          else {
              holder = (ViewHolder)convertView.getTag();
          }
          int lvCount = lv.getCount();  // for debugging
          //Must set this in both cases        
          holder.itemView.setText(listItems.get(position));  //BOOM
  
  
          return convertView;
  
      }  // end getView
  </code></pre>
  
  <p>Since the adapter knows there are only 6 items in its dataset, listItems, it should only call <em>getView()</em> with [0]-[5], but in fact it calls it with position values up to [11], which was the maximum value of the old list.  That's why it's crashing.   You can see where I also get the ListView's count, for diagnostics; it's also 6.   So where are the higher position values coming from? </p>