Android: duplicate items in ListVew. Maybe getView() called too many times?
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.
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?
Here is my shopping cart's layout XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Shopping Cart" />
<ScrollView android:id="@+id/ScrollView01"
android:layout_width="fill_parent"
android:layout_height="110px">
<ListView
android:id="@+id/BookList"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView>
</ScrollView>
<Button android:text="Add Another Book"
android:id="@+id/AddAnother"
android:layout_width="250px"
android:textSize="18px"
android:layout_height="55px">
</Button>
<Button android:text="Checkout"
android:id="@+id/Checkout"
android:layout_width="250px"
android:textSize="18px"
android:layout_height="55px">
</Button>
</LinearLayout>
Here is the layout for individual row items:
<?xml version="1.0" encoding="utf-8"?>
<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">
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="fill_parent">
<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"
/>
<TextView
android:id="@+id/BookPrice"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:singleLine="true"
android:ellipsize="marquee"
/>
</LinearLayout>
<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"
/>
</LinearLayout>
here is the java code for the shopping cart activity:
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 && shoppingCart.m_books.size() > 0)
{
//m_adapter.notifyDataSetChanged();
try
{
//m_adapter.clear();
//for(int i=0;i<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<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<Book> 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<Book> {
private ArrayList<Book> books;
public BookAdapter(Context _context, int _textViewResourceId, ArrayList<Book> _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;
}
}
}
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.
I had an issue iterating through the books in onCreate()
as well.开发者_如何学编程 the size()
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.
I'm doing exactly the same thing and my getView is not called at all. here is the script I was inspired by maybe it would help : http://mfarhan133.wordpress.com/2010/10/14/list-view-tutorial-for-android/
Yes you are right at the point of BookAdapter
's constructor. But the getView()
method of BookAdapter
is wrong. Please have a look at http://www.youtube.com/watch?v=wDBM6wVEO70 (from Google) to get the right way on how to work with ListView
.
Removing the loop where I had this fixed the problem:
m_adapter.add(shoppingCart.m_books.get(i));
It seems like the BookAdapter
constructor already took care of populating it, so I was duplicating the items by using the add()
method.
精彩评论