List items position repeating in getview
Solution 1
This sounds like a case of View re-cyclcing. Android will pass a pre-populated view to the getView method. It does so to minimize object creation. When an existing row-view is scrolled off screen, Android might try to recycle that view to display a row that is now on-screen. You need to account for the fact that this view may have been used to display data for another row (which is now off screen).
You have the following line
holder.typeProduct.setText
within the following conditional:
if(convertView == null){
Move that line outside of the conditional, and all should be well.
Solution 2
It's like EJK said. You are not recycling your view correctly. Change your code to this and notice where I put the setText calls
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = inflater.inflate(R.layout.product_list_details,parent, false);
holder=new ViewHolder();
holder.nameProduct =(TextView)convertView.findViewById(R.id.name);
holder.typeProduct =(TextView)convertView.findViewById(R.id.product);
holder.priceRangeProduct =(TextView)convertView.findViewById(R.id.pricerange);
holder.productImage =(ImageView)convertView.findViewById(R.id.image);
holder.plusImage =(ImageView)convertView.findViewById(R.id.dot);
holder.mainLayout = (RelativeLayout)convertView.findViewById(R.id.mainlayout);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
holder.plusImage.setTag(Integer.toString(position));
holder.plusImage.setOnClickListener(this);
holder.mainLayout.setTag(Integer.toString(position));
holder.mainLayout.setOnClickListener(this);
//setText functions are here
holder.nameProduct.setText(productName[position]);
if(producttype[position].length()>18)
{
holder.typeProduct.setText(producttype[position].substring(0,18)+"...");
}
else
{
holder.typeProduct.setText(producttype[position]);
}
holder.priceRangeProduct.setText(priceRangeFrom[position].substring(0,priceRangeFrom[position].length()-2)+" To "+priceRangeTo[position].substring(0, priceRangeTo[position].length()-2));
imageLoader.DisplayImage(productImage[position], holder.productImage);
return convertView;
}
Solution 3
Change your getView
to
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = inflater.inflate(R.layout.product_list_details,parent, false);
holder=new ViewHolder();
holder.nameProduct =(TextView)convertView.findViewById(R.id.name);
holder.typeProduct =(TextView)convertView.findViewById(R.id.product);
holder.priceRangeProduct =(TextView)convertView.findViewById(R.id.pricerange);
holder.productImage =(ImageView)convertView.findViewById(R.id.image);
holder.plusImage =(ImageView)convertView.findViewById(R.id.dot);
holder.mainLayout = (RelativeLayout)convertView.findViewById(R.id.mainlayout);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.nameProduct.setText(productName[position]);
if(producttype[position].length()>18)
{
holder.typeProduct.setText(producttype[position].substring(0,18)+"...");
}
else
{
holder.typeProduct.setText(producttype[position]);
}
holder.priceRangeProduct.setText(priceRangeFrom[position].substring(0,priceRangeFrom[position].length()-2)+" To "+priceRangeTo[position].substring(0, priceRangeTo[position].length()-2));
imageLoader.DisplayImage(productImage[position], holder.productImage);
holder.plusImage.setTag(Integer.toString(position));
holder.plusImage.setOnClickListener(this);
holder.mainLayout.setTag(Integer.toString(position));
holder.mainLayout.setOnClickListener(this);
return convertView;
}
Also check this
How ListView's recycling mechanism works
Solution 4
Change getView()
Declare ViewHolder
before if (convertView == null)
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.product_list_details,
parent, false);
holder = new ViewHolder();
holder.nameProduct = (TextView) convertView.findViewById(R.id.name);
holder.typeProduct = (TextView) convertView
.findViewById(R.id.product);
holder.priceRangeProduct = (TextView) convertView
.findViewById(R.id.pricerange);
holder.productImage = (ImageView) convertView
.findViewById(R.id.image);
holder.plusImage = (ImageView) convertView.findViewById(R.id.dot);
holder.mainLayout = (RelativeLayout) convertView
.findViewById(R.id.mainlayout);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.nameProduct.setText(productName[position]);
if (producttype[position].length() > 18) {
holder.typeProduct.setText(producttype[position].substring(0, 18)
+ "...");
} else {
holder.typeProduct.setText(producttype[position]);
}
holder.priceRangeProduct.setText(priceRangeFrom[position].substring(0,
priceRangeFrom[position].length() - 2)
+ " To "
+ priceRangeTo[position].substring(0,
priceRangeTo[position].length() - 2));
imageLoader.DisplayImage(productImage[position], holder.productImage);
holder.plusImage.setTag(Integer.toString(position));
holder.plusImage.setOnClickListener(this);
holder.mainLayout.setTag(Integer.toString(position));
holder.mainLayout.setOnClickListener(this);
return convertView;
}
Sanu
Updated on June 14, 2022Comments
-
Sanu almost 2 years
I am creating a custom list view using baseadapter.i have 10 list item in my list.my problem is that afetr 6 items ,the first 4 are repeating.i just printed position values in getview.it gives 0,1,2,3,4,5,6,7,8,9,0,1,2,3.My code is below.
thanx in advance
public class ProductListAdapter extends BaseAdapter implements OnClickListener{ /* * developer :sanu * date :10-4-2013 * time :3.34 pm */ public View row; private String[] productName; private String[] producttype; private String[] priceRangeFrom; private String[] priceRangeTo; private String[] productImage; private Activity activity; private static LayoutInflater inflater=null; static String posClicked; ViewHolder holder; Integer height1; Integer width1; Typeface tf; Integer FirmaCount; public ImageLoader imageLoader; public ProductListAdapter(Activity a,String[] name,String[] type,String[] price_from,String[] price_to,String[] image,Typeface tf) { activity = a; productName = name; producttype = type; priceRangeFrom = price_from; priceRangeTo = price_to; productImage = image; inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); imageLoader=new ImageLoader(activity.getApplicationContext()); } public int getCount() { return productName.length; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public int getViewTypeCount (int position) { return position; } public static class ViewHolder{ public TextView nameProduct; public TextView typeProduct; public TextView priceRangeProduct; public ImageView productImage; public ImageView plusImage; public RelativeLayout mainLayout; public int position; } public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null){ convertView = inflater.inflate(R.layout.product_list_details,parent, false); holder=new ViewHolder(); holder.nameProduct =(TextView)convertView.findViewById(R.id.name); holder.typeProduct =(TextView)convertView.findViewById(R.id.product); holder.priceRangeProduct =(TextView)convertView.findViewById(R.id.pricerange); holder.productImage =(ImageView)convertView.findViewById(R.id.image); holder.plusImage =(ImageView)convertView.findViewById(R.id.dot); holder.mainLayout = (RelativeLayout)convertView.findViewById(R.id.mainlayout); holder.nameProduct.setText(productName[position]); if(producttype[position].length()>18) { holder.typeProduct.setText(producttype[position].substring(0,18)+"..."); } else { holder.typeProduct.setText(producttype[position]); } holder.priceRangeProduct.setText(priceRangeFrom[position].substring(0,priceRangeFrom[position].length()-2)+" To "+priceRangeTo[position].substring(0, priceRangeTo[position].length()-2)); imageLoader.DisplayImage(productImage[position], holder.productImage); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } holder.plusImage.setTag(Integer.toString(position)); holder.plusImage.setOnClickListener(this); holder.mainLayout.setTag(Integer.toString(position)); holder.mainLayout.setOnClickListener(this); return convertView; }
-
Sanu over 10 yearsThanx for your reply....but on scrolling list item i got error in holder = (ViewHolder) convertView.getTag();
-
Raghunandan over 10 years@Sanu als why do you need
public int position
in view holder? -
Sanu over 10 yearsFATAL EXCEPTION: main java.lang.ClassCastException: java.lang.String cannot be cast to com.Adapter.ProductListAdapter$ViewHolder om.Adapter.ProductListAdapter.getView(ProductListAdapter.java:87) android.widget.AbsListView.obtainView(AbsListView.java:2063) android.widget.ListView.makeAndAddView(ListView.java:1792) android.widget.ListView.fillDown(ListView.java:676) 11-09 12:35:29.339: E/AndroidRuntime(4245): at android.widget.ListView.fillGap(ListView.java:640)
-
Sanu over 10 yearsFATAL EXCEPTION: main java.lang.ClassCastException: java.lang.String cannot be cast to com.Adapter.ProductListAdapter$ViewHolder om.Adapter.ProductListAdapter.getView(ProductListAdapter.java:87) android.widget.AbsListView.obtainView(AbsListView.java:2063) android.widget.ListView.makeAndAddView(ListView.java:1792) android.widget.ListView.fillDown(ListView.java:676) 11-09 12:35:29.339: E/AndroidRuntime(4245): at android.widget.ListView.fillGap(ListView.java:640)
-
Raghunandan over 10 years@Sanu productImage is a string array. i suggest you change it to something coz you have productImage as imageview in your holder. pls rename your variables to avoid confusion. Similarly rename others also. That would make debugging a lot simpler and help solve your problem
-
Amit Gupta over 10 years@Sanu can you tell me in which line the error is pointing. share that line of code.
-
Sanu over 10 yearsi just changed the imageview name.but getting the same issue
-
Sanu over 10 yearsholder = (ViewHolder) convertView.getTag();
-
Sanu over 10 yearson scrolling iget error on this line holder = (ViewHolder)convertView.getTag();
-
Sanu over 10 years11-09 15:17:39.757: E/AndroidRuntime(7145): FATAL EXCEPTION: main 11-09 15:17:39.757: E/AndroidRuntime(7145): java.lang.ClassCastException: java.lang.String cannot be cast to com.Adapter.ProductListAdapter$ViewHolder 11-09 15:17:39.757: E/AndroidRuntime(7145): at com.Adapter.ProductListAdapter.getView(ProductListAdapter.java:93)
-
Sanu over 10 years11-09 15:17:39.757: E/AndroidRuntime(7145): at android.widget.ListView.makeAndAddView(ListView.java:1792) 11-09 15:17:39.757: E/AndroidRuntime(7145): at android.widget.ListView.fillDown(ListView.java:676) 11-09 15:17:39.757: E/AndroidRuntime(7145): at android.widget.ListView.fillGap(ListView.java:640) 11-09 15:17:39.757: E/AndroidRuntime(7145): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4901)
-
Wang over 10 yearsAre you sure your code is still the same as in your starting post? The first exception implies that you called convertView.setTag with a String parameter somewhere. Please make sure your code is unchanged compared to your starting post when applying my suggestion.