title: android custom list view adapter doesnt update number of views in getView
body: <p>I have a listView with a custom adapter. 
  I have an edit text view in my activity where the user can type to filter the content on the list view.</p>
  
  <p>Lets say I have two items on the list view. After doing the filter, the ArrayList is reduced to one element.
  The problem is that the getView method is still executed for the two previous rows.</p>
  
  <p>Here is my code.</p>
  
  <p>ListActivity:</p>
  
  <pre><code>public class TeamsListActivity extends ListActivity {
  
      private ArrayList&lt;Team&gt; teams = new ArrayList&lt;Team&gt;();
      private TeamsListAdapter teamsListAdapter = null;
      private EditText searchInput = null;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.teams_list);
  
          // get association id from the intent.
          int afId = getIntent().getExtras().getInt("afId");
          Log.i(MainActivity.TAG, "id_association =" + afId);
  
          // get the teams from the association.
          this.teams = TeamsDAO.getInstance(getApplicationContext())
                  .getTeamsByAssociation(afId);
  
  
          // inits the list adapter
          teamsListAdapter = new TeamsListAdapter(this, teams);
  
          setListAdapter(teamsListAdapter);
  
          // gets the search input view
          searchInput = (EditText) findViewById(R.id.teams_list_search_box);
          searchInput.addTextChangedListener(new TextWatcher() {
  
              public void onTextChanged(CharSequence s, int start, int before, int count) {
  
              }
  
              public void beforeTextChanged(CharSequence s, int start, int count,
                      int after) {
  
              }
  
              public void afterTextChanged(Editable s) {
                  Log.d(Constants.TAG,"Teams search: " + s.toString());
                  teamsListAdapter.getFilter().filter(s);             
              }
          });
  
      }
  
  
  }
  </code></pre>
  
  <p><strong>My adapter</strong></p>
  
  <pre><code>public class TeamsListAdapter extends ArrayAdapter&lt;Team&gt; implements Filterable {
  
      private ArrayList&lt;Team&gt; teams = null;
      private Context context = null;
  
      public TeamsListAdapter(Context context,
              ArrayList&lt;Team&gt; objects) {
  
          super(context, R.layout.teams_list_row, objects);
  
          this.context = context;
          this.teams = objects;
  
      }
  
      @Override
      public View getView(int position, View v, ViewGroup parent) {
  
          if (v == null) {
              LayoutInflater vi = (LayoutInflater) context
                      .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              v = vi.inflate(R.layout.teams_list_row, null);
          }
  
              Team t = teams.get(position);
              if (t != null) {
  
                  TextView txtTeamName = (TextView) v.findViewById(R.id.teams_list_team_name);
  
                  txtTeamName.setText(t.getName());
  
                  ImageView ivTeamLogo = (ImageView) v.findViewById(R.id.teams_list_team_logo);
                  ivTeamLogo.setImageResource(R.drawable.af_braga);
              }
  
  
  
          return v;
      }
  
  
      @Override
      public Filter getFilter() {
          return new Filter() {
  
              @SuppressWarnings("unchecked")
              @Override
              protected void publishResults(CharSequence constraint, FilterResults results) {
                    Log.d(Constants.TAG, "**** Search RESULTS for: " + constraint);
                     teams = (ArrayList&lt;Team&gt;) results.values;
                     Log.d(Constants.TAG,"size:"+teams.size());
                     TeamsListAdapter.this.notifyDataSetChanged();
  
              }
  
              @Override
              protected FilterResults performFiltering(CharSequence constraint) {
                  Log.d(Constants.TAG, "**** PERFORM TEAK FILTERING for: " + constraint);
                  ArrayList&lt;Team&gt; filteredResults = getFilteredResults(constraint);
  
                  FilterResults results = new FilterResults();
                  results.values = filteredResults;
  
                  return results;
              }
  
              /**
               * filters the teamsList 
               * @param constraint String The text to search
               * @return ArrayList&lt;Team&gt;
               */
              private ArrayList&lt;Team&gt; getFilteredResults(CharSequence constraint) {
                  ArrayList&lt;Team&gt; teams = TeamsListAdapter.this.teams;
                  ArrayList&lt;Team&gt; filteredTeams = new ArrayList&lt;Team&gt;();
                  for(int i=0;i&lt; teams.size();i++){
                      if(teams.get(i).getName().toLowerCase().startsWith(constraint.toString().toLowerCase())){
                          filteredTeams.add(teams.get(i));
                      }
                  }
  
                  return filteredTeams;
              }
          };
  
      }
  }
  </code></pre>
  
  <p><strong>Clarification of the problem.</strong></p>
  
  <p>1.Let´s say my list starts showing two elements. 
  2. The user inserts some text in the edit text to filter the list content which results in a updated arrayList with only one element who matches the query.
  3. After called the notifyDataSetChanged the getView still is called like there was two rows in the dataset resulting in IndexOutOfBoundsException when executing Team t = teams.get(position) becuase the arrayList has only one element now so when position = 1 => the get(postion) fails.</p>
  
  <p>Hope its clear now.</p>