Позиция элементов списка повторяется в getview

Я создаю собственное представление списка, используя baseadapter. У меня есть 10 элементов списка в моем списке. Моя проблема в том, что после 6 элементов первые 4 повторяются. Я просто напечатал значения позиции в getview. Это дает 0,1,2,3 ,4,5,6,7,8,9,0,1,2,3. Мой код ниже.

спасибо заранее

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;
} 

person Sanu    schedule 09.11.2013    source источник
comment
переместите этот holder.nameProduct.setText(productName[position]); if(producttype[position].length()>18) { holder.typeProduct.setText(producttype[position].substring(0,18)+"..."); } else { holder.typeProduct.setText(producttype[position]); } ниже последнего и попробуйте   -  person Raghunandan    schedule 09.11.2013
comment
вместо этого я предлагаю расширить ArrayAdapter, так как вы можете выполнить то же действие, что и выше, с меньшими соображениями.   -  person ManZzup    schedule 09.11.2013


Ответы (4)


Это похоже на повторный цикл View. Android передаст предварительно заполненное представление методу getView. Это делается для того, чтобы свести к минимуму создание объектов. Когда существующее представление строки прокручивается за пределы экрана, Android может попытаться переработать это представление, чтобы отобразить строку, которая сейчас находится на экране. Вам необходимо учитывать тот факт, что это представление могло использоваться для отображения данных для другой строки (которая теперь находится за пределами экрана).

У вас есть следующая строка

holder.typeProduct.setText

в следующем условном:

if(convertView == null){            

Переместите эту строку за пределы условного оператора, и все должно быть хорошо.

person EJK    schedule 09.11.2013

Это как сказал EJK. Вы неправильно перерабатываете свое представление. Измените свой код на этот и обратите внимание, где я помещаю вызовы setText

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;
} 
person Wang    schedule 09.11.2013
comment
при прокрутке ошибки iget в этой строке держатель = (ViewHolder)convertView.getTag(); - person Sanu; 09.11.2013
comment
11-09 15:17:39.757: E/AndroidRuntime(7145): НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: main 11-09 15:17:39.757: E/AndroidRuntime(7145): java.lang.ClassCastException: java.lang.String нельзя преобразовать в com.Adapter.ProductListAdapter$ViewHolder 11-09 15:17:39.757: E/AndroidRuntime(7145): в com.Adapter.ProductListAdapter.getView(ProductListAdapter.java:93) - person Sanu; 09.11.2013
comment
11-09 15:17:39.757: E/AndroidRuntime(7145): на android.widget.ListView.makeAndAddView(ListView.java:1792) 11-09 15:17:39.757: E/AndroidRuntime(7145): на android. widget.ListView.fillDown(ListView.java:676) 11-09 15:17:39.757: E/AndroidRuntime(7145): в android.widget.ListView.fillGap(ListView.java:640) 11-09 15:17: 39.757: E/AndroidRuntime(7145): в android.widget.AbsListView.trackMotionScroll(AbsListView.java:4901) - person Sanu; 09.11.2013
comment
Вы уверены, что ваш код все еще такой же, как в вашем стартовом посте? Первое исключение подразумевает, что вы где-то вызвали convertView.setTag с параметром String. Пожалуйста, убедитесь, что ваш код не изменился по сравнению с вашим начальным постом при применении моего предложения. - person Wang; 09.11.2013

Измените свой getView на

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;
} 

Также проверьте это

Как работает механизм повторного использования ListView

person Raghunandan    schedule 09.11.2013
comment
Спасибо за ваш ответ.... но при прокрутке элемента списка я получил ошибку в держателе = (ViewHolder) convertView.getTag(); - person Sanu; 09.11.2013
comment
@Sanu также зачем тебе public int position в держателе представления? - person Raghunandan; 09.11.2013
comment
НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: main java.lang.ClassCastException: java.lang.String нельзя преобразовать в 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): в android .widget.ListView.fillGap(ListView.java:640) - person Sanu; 09.11.2013
comment
@Sanu productImage — это массив строк. я предлагаю вам изменить его на что-то, потому что у вас есть productImage как изображение в вашем держателе. Пожалуйста, переименуйте свои переменные, чтобы избежать путаницы. Аналогичным образом переименуйте и другие. Это значительно упростит отладку и поможет решить вашу проблему. - person Raghunandan; 09.11.2013
comment
я только что изменил имя изображения. но получаю ту же проблему - person Sanu; 09.11.2013

Изменить getView()

Объявить ViewHolder до 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;
    }
person Amit Gupta    schedule 09.11.2013
comment
НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: main java.lang.ClassCastException: java.lang.String нельзя преобразовать в 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): в android .widget.ListView.fillGap(ListView.java:640) - person Sanu; 09.11.2013
comment
@ Сану, не могли бы вы сказать мне, на какую строку указывает ошибка? поделитесь этой строкой кода. - person Amit Gupta; 09.11.2013
comment
держатель = (ViewHolder) convertView.getTag(); - person Sanu; 09.11.2013