title: ListView - Custom Adapter - Values keep changing when scrolling
body: <p>Android 2.3.3</p>
  
  <p>I am using a Custom Adapter to fill a listview. Each row in a listview has 3 textviews(Custom Layout), that are filled from the data retrieved from database.</p>
  
  <p>The problem is, the data is being displayed correctly, the first time. But when I scroll down and then scroll up the listview again, the rows at the top of the listview are replaced by the rows at the bottom and when I scroll down, they are again being replaced by the rows that are currently being displayed.</p>
  
  <p>I thought the problem could be recreation of the rows and I should use viewHolder. Even though I did use the viewHolder, it doesn't solve the problem.</p>
  
  <p>Here is the code...</p>
  
  <pre><code>class MyCustomAdapter extends BaseAdapter{
  
      @Override
      public int getCount() {
          // TODO Auto-generated method stub
          return c.getCount();
      }
  
      @Override
      public Object getItem(int position) {
          // TODO Auto-generated method stub
          return position;
      }
  
      @Override
      public long getItemId(int position) {
          // TODO Auto-generated method stub
          return position;
      }
  
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          // TODO Auto-generated method stub
  
          HistoryViewHolder viewHolder;
  
              if(convertView == null)
              {
                  LayoutInflater li = getLayoutInflater();
                  convertView =  li.inflate(R.layout.history_row, null);
  
                  viewHolder = new HistoryViewHolder();
  
                  viewHolder.txtcnt = (TextView) convertView.findViewById(R.id.txtView_History_Count);
                  viewHolder.txtexp = (TextView) convertView.findViewById(R.id.txtView_History_Expression);
                  viewHolder.txtres = (TextView) convertView.findViewById(R.id.txtView_History_Result);
  
                  convertView.setTag(viewHolder);
              }
              else
              {
                  viewHolder = (HistoryViewHolder) convertView.getTag();
              }
  
  
              if(!c.isAfterLast())
              {
  
                  viewHolder.txtcnt.setText(String.valueOf(position + 1));        
                  System.out.println("Position"+viewHolder.txtcnt.getText().toString());
  
                  expression = c.getString(c.getColumnIndex("expression"));
                  result = c.getString(c.getColumnIndex("result"));
  
                  c.moveToPosition(position + 1);
  
                  viewHolder.txtexp.setText(expression);
                  System.out.println("Expression"+viewHolder.txtexp.getText().toString());
                  viewHolder.txtres.setText(result);      
                  System.out.println("Result"+viewHolder.txtres.getText().toString());
  
              }   
  
          return convertView;
      }
  
  
      public class HistoryViewHolder {
          TextView txtcnt;
          TextView txtexp;
          TextView txtres;
      }
  
  }
  </code></pre>
  
  <p>Am I using the viewHolder correctly? Why do we need to use the viewHolder? What is the use exactly?</p>
  
  <p>EDIT ::: As suggested by vmironov ::: I have removed the <code>if(!c.isAfterLast())</code> and changed the <code>c.moveToPosition(position + 1)</code> to <code>c.moveToPosition(position)</code>. Now, the replacement doesn't happen, but the first element is being repeated twice and the last entry is not being displayed. And when i scroll down and up again, the first two rows are not being displayed. </p>
  
  <p>EDIT 2 ::: Just moved the <code>c.moveToPosition(position)</code> above expression = <code>c.getString(c.getColumnIndex("expression"));</code></p>
  
  <p>I am posting the entire code, if needed have a look...</p>
  
  <pre><code>@Override
  public View getView(int position, View convertView, ViewGroup parent) {
      // TODO Auto-generated method stub
  
      HistoryViewHolder viewHolder;
  
          if(convertView == null)
          {
              LayoutInflater li = getLayoutInflater();
              convertView =  li.inflate(R.layout.history_row, null);
  
              viewHolder = new HistoryViewHolder();
  
              viewHolder.txtcnt = (TextView) convertView.findViewById(R.id.txtView_History_Count);
              viewHolder.txtexp = (TextView) convertView.findViewById(R.id.txtView_History_Expression);
              viewHolder.txtres = (TextView) convertView.findViewById(R.id.txtView_History_Result);
  
              convertView.setTag(viewHolder);
          }
          else
          {
              viewHolder = (HistoryViewHolder) convertView.getTag();
          }
  
              viewHolder.txtcnt.setText(String.valueOf(position + 1));        
              System.out.println("Position"+viewHolder.txtcnt.getText().toString());
  
              c.moveToPosition(position);
  
              expression = c.getString(c.getColumnIndex("expression"));
              result = c.getString(c.getColumnIndex("result"));
  
              viewHolder.txtexp.setText(expression);
              System.out.println("Expression"+viewHolder.txtexp.getText().toString());
              viewHolder.txtres.setText(result);      
              System.out.println("Result"+viewHolder.txtres.getText().toString());            
  
  
      return convertView;
  }
  
  
  public class HistoryViewHolder {
      TextView txtcnt;
      TextView txtexp;
      TextView txtres;
  }
  </code></pre>
  
  <p>}</p>