在getview中重复列出项目位置

Posted

技术标签:

【中文标题】在getview中重复列出项目位置【英文标题】:List items position repeating in getview 【发布时间】:2013-11-21 07:10:35 【问题描述】:

我正在使用 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;
 

【问题讨论】:

把这个holder.nameProduct.setText(productName[position]); if(producttype[position].length()>18) holder.typeProduct.setText(producttype[position].substring(0,18)+"..."); else holder.typeProduct.setText(producttype[position]); 移到最后一个else下面试试 我建议改为扩展 ArrayAdapter,因为您可以在较少考虑的情况下执行与上述相同的操作 【参考方案1】:

这听起来像是视图再循环的情况。 android 会将预先填充的视图传递给 getView 方法。这样做是为了尽量减少对象创建。当现有的行视图滚动到屏幕外时,Android 可能会尝试回收该视图以显示现在在屏幕上的行。您需要考虑这样一个事实,即该视图可能已用于显示另一行的数据(现在不在屏幕上)。

你有以下行

holder.typeProduct.setText

在以下条件内:

if(convertView == null)            

将那条线移到条件之外,一切都会好起来的。

【讨论】:

【参考方案2】:

就像 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;
 

【讨论】:

在此行持有者上滚动 iget 错误 = (ViewHolder)convertView.getTag(); 11-09 15:17:39.757:E/AndroidRuntime(7145):致命异常:主要 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): at com.Adapter.ProductListAdapter.getView(ProductListAdapter.java:93) 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) 您确定您的代码仍与您的起始帖子中的代码相同吗?第一个例外意味着您在某处调用了带有 String 参数的 convertView.setTag。应用我的建议时,请确保您的代码与您的起始帖子相比没有变化。【参考方案3】:

将您的 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;
 

也检查一下

How ListView's recycling mechanism works

【讨论】:

感谢您的回复....但是在滚动列表项上我在 holder = (ViewHolder) convertView.getTag(); 中遇到错误; @Sanu 也为什么你需要public int position 在视图支架中? 致命异常:主要 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) @Sanu productImage 是一个字符串数组。我建议您将其更改为某些内容,因为您的支架中有 productImage 作为 imageview。请重命名您的变量以避免混淆。同样重命名其他人也。这将使调试变得更简单,并有助于解决您的问题 我只是更改了图像视图名称。但遇到了同样的问题【参考方案4】:

改变 getView()

if (convertView == null) 之前声明ViewHolder

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

【讨论】:

致命异常:主要 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) @Sanu 你能告诉我错误指向哪一行吗?分享那行代码。 holder = (ViewHolder) convertView.getTag();

以上是关于在getview中重复列出项目位置的主要内容,如果未能解决你的问题,请参考以下文章

位置索引在 getView 中总是返回 0

在适配器中使用 getView 方法的优化方法 [重复]

Android,列表适配器在getView中返回错误的位置

适配器 getView 被多次调用,位置为 0

为啥我的 BaseAdapter 类不增加 getView 中的位置?

如何限制getView中特定项目的某些代码的执行?