title: Android: duplicate items in ListVew. Maybe getView() called too many times?
body: <p>I am trying to create a simple program which displays a "shopping
  cart" list of items, along with a few buttons below it to manage the
  cart.</p>
  
  <p>The biggest problem is that items are getting duplicate entries in the
  list view.  That is, for every item I want to enter I see it appear
  two times in the list view.  What's the problem?  Also, the scrollable
  area of my cart is not big enough.  How do I set it so that it is
  bigger but I can still see my buttons?  Perhaps I should put the
  buttons above the cart?</p>
  
  <p>Here is my shopping cart's layout XML:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"&gt;
  
      &lt;TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Shopping Cart" /&gt;
  
      &lt;ScrollView android:id="@+id/ScrollView01"
          android:layout_width="fill_parent"
          android:layout_height="110px"&gt;
  
          &lt;ListView
              android:id="@+id/BookList"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"&gt;
          &lt;/ListView&gt;
  
      &lt;/ScrollView&gt;
  
      &lt;Button android:text="Add Another Book"
          android:id="@+id/AddAnother"
          android:layout_width="250px"
          android:textSize="18px"
          android:layout_height="55px"&gt;
      &lt;/Button&gt;
  
      &lt;Button android:text="Checkout"
          android:id="@+id/Checkout"
          android:layout_width="250px"
          android:textSize="18px"
          android:layout_height="55px"&gt;
      &lt;/Button&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>Here is the layout for individual row items:   </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="?android:attr/listPreferredItemHeight"
      android:padding="8dip"&gt;
  
      &lt;LinearLayout
          android:orientation="vertical"
          android:layout_width="0dip"
          android:layout_weight="1"
          android:layout_height="fill_parent"&gt;
  
          &lt;TextView
              android:id="@+id/BookTitle"
              android:layout_width="fill_parent"
              android:layout_height="0dip"
              android:layout_weight="1"
              android:singleLine="true"
              android:gravity="center_vertical"
          /&gt;
  
          &lt;TextView
              android:id="@+id/BookPrice"
              android:layout_width="fill_parent"
              android:layout_height="0dip"
              android:layout_weight="1"
              android:singleLine="true"
              android:ellipsize="marquee"
          /&gt;
      &lt;/LinearLayout&gt;
  
      &lt;Button
          android:id="@+id/buttonLine"
          android:gravity="center"
          android:layout_height="wrap_content"
          android:layout_width="wrap_content"
          android:layout_alignParentRight="true"
          android:text="Delete"
      /&gt;
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>here is the java code for the shopping cart activity:</p>
  
  <pre><code>package com.sellbackyourbook.sellback;
  
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.Iterator;
  
  import android.app.Activity;
  //import android.app.ListActivity;
  import android.content.Context;
  import android.content.Intent;
  import android.net.Uri;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.ArrayAdapter;
  import android.widget.Button;
  import android.widget.ListView;
  import android.widget.TextView;
  
  public class cart extends Activity 
  {
      private ListView m_bookListView;
      private BookAdapter m_adapter;
  
      //private static String[] data = new String[] = { ""
  
      /** Called when the activity is first created. */
      public void onCreate(Bundle savedInstanceState) 
      {
          ShoppingCartSingleton shoppingCart = ShoppingCartSingleton.getInstance();
  
          super.onCreate(savedInstanceState);
          setContentView(R.layout.shoppingcart);
  
          this.m_adapter = new BookAdapter(this, R.layout.cartitem,
              shoppingCart.m_books);
  
          m_bookListView = (ListView) findViewById(R.id.BookList);
          m_bookListView.setAdapter(this.m_adapter);
  
          //setListAdapter(this.m_adapter);
  
          if (shoppingCart.m_books != null &amp;&amp; shoppingCart.m_books.size() &gt; 0)
          {
              //m_adapter.notifyDataSetChanged();
  
              try
              {
  
              //m_adapter.clear();
                  //for(int i=0;i&lt;1;i++)
  
              Log.i("ARRAY", "m_books.size() before loop" + shoppingCart.m_books.size());
  
              int size = shoppingCart.m_books.size();
  
              for(int i=0;i&lt;size;i++)
              {   
                  Log.i("ARRAY", "size in loop" + size);
                  Log.i("ARRAY", "adding item to adapter" + i);
                  m_adapter.add(shoppingCart.m_books.get(i));
              }
  
          } catch (RuntimeException e) {
              e.printStackTrace();
          }
  
          //m_adapter.notifyDataSetChanged();
          }
  
          Button buttonAddAnother = (Button) findViewById(R.id.AddAnother);
          buttonAddAnother.setOnClickListener(new View.OnClickListener() 
          {
              public void onClick(View view) 
              {
                  Intent intent = new Intent();
                  setResult(RESULT_OK, intent);
                  finish();
              }
          });
  
          // TODO: only show this button if the shopping cart is not empty
  
          Button buttonCheckout = (Button) findViewById(R.id.Checkout);
          buttonCheckout.setOnClickListener(new View.OnClickListener() 
          {
              public void onClick(View view) 
              {
                  // TODO: open sellbackyourbook website using book ISBNs
  
                  ShoppingCartSingleton shoppingCart = ShoppingCartSingleton.getInstance();
  
                  String isbnList = "";
                  String checkoutURL = "http://www.sellbackyourbook.com/androidcart.php?isbn=";
  
                  for (Iterator&lt;Book&gt; i = shoppingCart.m_books.iterator(); i.hasNext();  )
                  {
                      Book currentBook = (Book) i.next();
                      isbnList = isbnList + currentBook.getBookISBN() + ","; 
                  }
  
                  checkoutURL = checkoutURL + isbnList;
                  Log.i("CHECKOUT URL", "checkout URL to submit: " + checkoutURL);
  
                  Intent myIntent = new Intent(Intent.ACTION_VIEW);
                  myIntent.setData(Uri.parse(checkoutURL));
                  startActivity(myIntent);
              }
          });
  
      }
  
      private class BookAdapter extends ArrayAdapter&lt;Book&gt; {
  
          private ArrayList&lt;Book&gt; books;
  
          public BookAdapter(Context _context, int _textViewResourceId, ArrayList&lt;Book&gt; _books) 
          {
                  super(_context, _textViewResourceId, _books);
                  this.books = _books;
          }
  
          @Override
          public View getView(int position, View convertView, ViewGroup parent) 
          {
  
              System.out.println("getView " + position + " " + convertView);
  
              View v = convertView;
  
                  if (v == null) {
                      LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                      v = vi.inflate(R.layout.cartitem, null);
                  }
  
                  Book b = books.get(position);
  
                  if (b != null) 
                  {
                      TextView bTitle = (TextView) v.findViewById(R.id.BookTitle);
                      TextView bPrice = (TextView) v.findViewById(R.id.BookPrice);
  
                          if (bTitle != null) 
                          {
                              bTitle.setText(b.getBookTitle());  
                          }
  
                          if (bPrice != null)
                          {
                              bPrice.setText(b.getBookPrice());
                          }
                  }
  
                  return v;
          }
      }   
  }
  </code></pre>
  
  <p>Here is the Java code for my shopping cart.  Am I using the singleton correctly? I really just wanted a quick and dirty way to allow multiple activities access to the shopping cart, as a different activity actually grabs the books from the user and this activity displays them in the cart. </p>
  
  <p>I had an issue iterating through the books in <code>onCreate()</code> as well.  the <code>size()</code> function kept increasing in the loop for some reason, so I changed the code and added a "size" variable to avoid making the size() call in the loop itself.  I'm not really sure what that was all about.</p>