ListView的看法回收与CustomAdapter [英] ListView view recycling with CustomAdapter

查看:137
本文介绍了ListView的看法回收与CustomAdapter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我夸大两个不同的布局一个ListView。一切正常,直到我开始向下滚动,其中2个不同的布局开始被随机应用。我跟着就到这里其他的例子,但我不能得到它的工作。有什么建议?

 公共类CustomAdapter扩展了BaseAdapter {

    日期日期=新的日期();
    私人OfferList []优惠;
    私人字符串nameCompare =;

    CustomAdapter(OfferList []计划书,FetchItemsTask fetchItemsTask){
         this.offers =报价;
     }

    @覆盖
    公共查看getView(INT位置,查看convertView,ViewGroup中父){
        ViewHolder支架=无效;
        LayoutInflater充气= getLayoutInflater();
        如果(convertView == NULL){
            持有人=新ViewHolder();
            如果(nameCompare.equalsIgnoreCase(报价[位置] .getCustomerName())){
                convertView = inflater.inflate(R.layout.list_offer_group,NULL);
            }
            其他 {
                nameCompare =报价[位置] .getCustomerName();
                convertView = inflater.inflate(R.layout.list_offer,NULL);
            }
            holder.name =(TextView中)convertView.findViewById(R.id.name);
            holder.color =(TextView中)convertView.findViewById(R.id.color_stock);
            holder.time =(TextView中)convertView.findViewById(R.id.time);
            holder.offerStatus =(TextView中)convertView.findViewById(R.id.offer_status);

            convertView.setTag(保持器);

        }
        其他 {
            支架=(ViewHolder)convertView.getTag();
        }

        holder.name.setText(报价[位置] .getName());
        holder.carStockColor.setText(报价[位置] .getYear()++提供了[位置] .getVehicleMake());
        java.util.Date时间1 =新java.util.Date(的Long.parseLong(报价[位置] .getModified()));
        holder.time.setText(time1.toString()子(0,11)+|);
        holder.offerStatus.setText(报价[位置] .getStatus());
        返回convertView;

    }

公共类ViewHolder {
        TextView的名称;
        TextView的颜色;
        TextView的时间;
        TextView的offerStatus;
    }
 }
 

解决方案

您需要覆盖下面的方法:

https://developer.android.com/reference/android/widget/Adapter.html#getViewTypeCount()https://developer.android.com/reference/android/widget/Adapter.html#getItemViewType(int)

这些将让列表视图知道你有多少种看法已经和它的位置是哪种类型的。这将prevent列表视图,从传递不正确convertview类型到您的getView方法。

编辑:

让我们退后一步。您看到了这个问题的原因是ListView控件是通过不正确的convertView到您的getView()方法。默认getViewTypeCount()返回1,这样的ListView假设你只有一个视图类型。您正在使用您的行两种观点:R.layout.list_offer_group和R.layout.list_offer。当convertView不为空,你不检查,看看哪些布局convertView是 - 在某些情况下,这将是不正确的布局。

要解决这个问题:

覆盖getViewTypeCount返回2,因为你有两种不同的类型。覆盖getItemViewType使用您的组/非组逻辑

 公众诠释getItemViewType(INT位置){
  如果(nameCompare.equalsIgnoreCase(报价[位置] .getCustomerName())){
    返回0;
  } 其他 {
    返回1;
  }
}
 

这是现在正在返回0组和1个非团体。然后我们可以使用getItemViewType()在getView以确定哪​​些来看,我们都在用,所以:

 如果(nameCompare.equalsIgnoreCase(报价[位置] .getCustomerName())){
            convertView = inflater.inflate(R.layout.list_offer_group,NULL);
        }
        其他 {
            nameCompare =报价[位置] .getCustomerName();
            convertView = inflater.inflate(R.layout.list_offer,NULL);
        }
 

变成了:

 如果(getItemViewType(位置)== 0){
            convertView = inflater.inflate(R.layout.list_offer_group,NULL);
        }
        其他 {
            nameCompare =报价[位置] .getCustomerName();
            convertView = inflater.inflate(R.layout.list_offer,NULL);
        }
 

这应该修正自己的行为,因为现在的ListView知道你有2个视图类型(getViewTypeCount),并在列表中的行是哪种类型(getItemViewType)的。它将不再传递型组convertView成getView呼吁排式非组,反之亦然。

I'm inflating two different layouts for a ListView. Everything works until I start scrolling down where the 2 different layouts begin being applied randomly. I've followed other examples on here but I just can't get it to work. Any suggestions?

public class CustomAdapter extends BaseAdapter {

    Date date = new Date();
    private OfferList[] offers;
    private String nameCompare = "";

    CustomAdapter (OfferList[] offers, FetchItemsTask fetchItemsTask) { 
         this.offers = offers;
     }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        ViewHolder holder = null;
        LayoutInflater inflater = getLayoutInflater();          
        if (convertView == null) {
            holder = new ViewHolder();
            if (nameCompare.equalsIgnoreCase(offers[position].getCustomerName())) {
                convertView = inflater.inflate(R.layout.list_offer_group, null);
            }
            else {
                nameCompare = offers[position].getCustomerName();
                convertView = inflater.inflate(R.layout.list_offer, null);
            }
            holder.name = (TextView) convertView.findViewById(R.id.name);
            holder.color = (TextView) convertView.findViewById(R.id.color_stock);
            holder.time = (TextView) convertView.findViewById(R.id.time);
            holder.offerStatus = (TextView) convertView.findViewById(R.id.offer_status);

            convertView.setTag(holder);

        } 
        else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.name.setText(offers[position].getName());
        holder.carStockColor.setText(offers[position].getYear() + " " + offers[position].getVehicleMake());
        java.util.Date time1 = new java.util.Date(Long.parseLong(offers[position].getModified()));
        holder.time.setText(time1.toString().substring(0, 11) + " | ");
        holder.offerStatus.setText(offers[position].getStatus());
        return convertView;

    }

public class ViewHolder {
        TextView name;
        TextView color;
        TextView time;
        TextView offerStatus;
    }
 }

解决方案

You need to override the following methods:

https://developer.android.com/reference/android/widget/Adapter.html#getViewTypeCount() https://developer.android.com/reference/android/widget/Adapter.html#getItemViewType(int)

These will let the listview know how many types of views you have and which position is of which type. This will prevent the listview from passing the incorrect convertview type into your getView method.

EDIT:

Let's take a step back. The reason you are seeing this problem is ListView is passing the incorrect convertView into your getView() method. The default getViewTypeCount() returns 1, so listView assumes you only have one view type. You are using two types of views for your rows: R.layout.list_offer_group, and R.layout.list_offer. When convertView is not null, you are not checking to see which layout convertView is -- in some cases it will be the incorrect layout.

To remedy this:

override getViewTypeCount to return 2, since you have two different types. Override getItemViewType to use your group/non-group logic

public int getItemViewType(int position) {
  if (nameCompare.equalsIgnoreCase(offers[position].getCustomerName())) {
    return 0;
  } else {
    return 1;
  }
}

This is now returning 0 for groups and 1 for non-groups. Then we can use getItemViewType() in getView to determine which view we are using, so:

        if (nameCompare.equalsIgnoreCase(offers[position].getCustomerName())) {
            convertView = inflater.inflate(R.layout.list_offer_group, null);
        }
        else {
            nameCompare = offers[position].getCustomerName();
            convertView = inflater.inflate(R.layout.list_offer, null);
        }

becomes:

        if (getItemViewType(position) == 0) {
            convertView = inflater.inflate(R.layout.list_offer_group, null);
        }
        else {
            nameCompare = offers[position].getCustomerName();
            convertView = inflater.inflate(R.layout.list_offer, null);
        }

This should fix your behavior since now ListView knows you have 2 view types (getViewTypeCount) and which rows in your list are of which type (getItemViewType). It will no longer pass a convertView of type group into a getView call for a row of type non-group and vice versa.

这篇关于ListView的看法回收与CustomAdapter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆