Android自定义ArrayList适配器和游标的奇怪行为

Android自定义ArrayList适配器和游标的奇怪行为,android,listview,arraylist,cursor,adapter,Android,Listview,Arraylist,Cursor,Adapter,我有一个对象的自定义ArrayList适配器。在这个适配器中,我使用arrayListdeals提供的id创建了一个游标。 Listview中的项目有两种不同的布局,这取决于光标是否包含数据。 问题是上下滚动一段时间会导致listview在不同的项目上多次显示相同的游标数据。arrayList中的数据显示正确 图片: @覆盖 公共视图getView(int位置、视图转换视图、视图组父视图){ 视图行=转换视图; holder=null; 游标=空; cursor=db.getDealInfo2I

我有一个对象的自定义ArrayList适配器。在这个适配器中,我使用arrayList
deals
提供的id创建了一个游标。 Listview中的项目有两种不同的布局,这取决于光标是否包含数据。 问题是上下滚动一段时间会导致listview在不同的项目上多次显示相同的游标数据。arrayList中的数据显示正确

图片:

@覆盖
公共视图getView(int位置、视图转换视图、视图组父视图){
视图行=转换视图;
holder=null;
游标=空;
cursor=db.getDealInfo2ID(deals.get(position.getId());
int count=cursor.getCount();
if(行==null){
保持架=新保持架();
LayoutInflater充气器=LayoutInflater.from(parent.getContext());
如果(计数=0){
行=充气机。充气(布局资源ID,空);
holder.comment=null;
}
否则{
行=充气机。充气(R.layout.card\u row\u deal\u layout,空);
holder.price=(TextView)row.findViewById(R.id.price);
holder.icon=(ImageView)row.findViewById(R.id.icon);
holder.button=(button)row.findViewById(R.id.toDealButton);
holder.comment=(TextView)row.findViewById(R.id.comment);
}
holder.name=(TextView)row.findViewById(R.id.dealName);
holder.degree=(TextView)row.findViewById(R.id.degree);
holder.thermoColor=行findViewById(R.id.thermoColor);
holder.THERMOGRY=第行findViewById(R.id.THERMOGRY);
row.setTag(支架);
}
否则{
holder=(holder)行。getTag();
if(holder.comment==null&&count!=0){
LayoutInflater充气器=LayoutInflater.from(parent.getContext());
row=充气机。充气(R.layout.card\u row\u deal\u layout,parent,false);
holder.name=(TextView)row.findViewById(R.id.dealName);
holder.degree=(TextView)row.findViewById(R.id.degree);
holder.thermoColor=行findViewById(R.id.thermoColor);
holder.THERMOGRY=第行findViewById(R.id.THERMOGRY);
holder.price=(TextView)row.findViewById(R.id.price);
holder.icon=(ImageView)row.findViewById(R.id.icon);
holder.button=(button)row.findViewById(R.id.toDealButton);
holder.comment=(TextView)row.findViewById(R.id.comment);
row.setTag(支架);
}
}
//肖特卡贝弗伦酒店
holder.name.setText(deals.get(position.getName());
整数deg=deals.get(position.getDegree();
setDegreeView(数学abs(deg.intValue()),deg);
如果(计数!=0){
//德塔卡比伦酒店
填写卡片(光标);
}
cursor.close();
返回行;
}
私有无效填充详细信息卡(光标){
//普赖斯
String priceString=cursor.getString(cursor.getColumnIndex(SQLDataBaseHelper.COLUMN_PRICE));
if(priceString!=null)
holder.price.setText(priceString);
//DirectLinkButton
字符串url=cursor.getString(cursor.getColumnIndex(SQLDataBaseHelper.COLUMN_DIRECTLINK));
如果(url!=null){
holder.button.setText(R.string.directDeal);
holder.button.setBackgroundResource(R.drawable.to\u deal\u button\u background背景);
holder.button.setOnClickListener(新的ButtonDirectToListener(url,上下文));
}
否则{
holder.button.setText(“”);
holder.button.setBackgroundColor(安卓.R.color.白色);
holder.button.setOnClickListener(空);
}
//科门塔尔·安扎尔
holder.comment.setText(cursor.getString(cursor.getColumnIndex(SQLDataBaseHelper.COLUMN_COMMENTCOUNT));
//图片
stringpic=cursor.getString(cursor.getColumnIndex(SQLDataBaseHelper.COLUMN_pic));
如果(pic!=null){
支架.图标.立根(空);
holder.icon.setImageDrawable(空);
毕加索.load(pic).error(R.drawable.error).into(holder.icon);
}
否则{
支架.图标.立根(空);
holder.icon.setImageDrawable(空);
int sdk=android.os.Build.VERSION.sdk\u int;
if(sdk

我真的不知道问题出在哪里。希望您能提供帮助。

我已经仔细阅读了您的代码,我发现在以下情况下可能会发生这种情况:

int count = cursor.getCount(); //returns 0
if(row == null){ //returns false and row is R.layout.card_row_deal_layout
在这种情况下,您将忽略所有布局设置并跳过调用fillDetailCard

使用这一行
if(holder.comment==null&&count!=0){
检查布局是否应从
layoutResourceId
更改为
R.layout.card\u row\u deal\u layou
,但从不检查相反的方式

它可能是这样的:

holder = (Holder) row.getTag();
if(holder.comment==null && count !=0){
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    row = inflater.inflate(R.layout.card_row_deal_layout, parent, false);
    holder = new Holder();
    holder.name = (TextView)row.findViewById(R.id.dealName);
    holder.degree = (TextView)row.findViewById(R.id.degree);
    holder.thermoColor = row.findViewById(R.id.thermoColor);
    holder.thermoGrey = row.findViewById(R.id.thermoGrey);

    holder.price = (TextView) row.findViewById(R.id.price);
    holder.icon = (ImageView) row.findViewById(R.id.icon);
    holder.button = (Button) row.findViewById(R.id.toDealButton);
    holder.comment =  (TextView) row.findViewById(R.id.comment);
    row.setTag(holder);
} else if (holder.comment != null && count == 0) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    row = inflater.inflate(layoutResourceId, null);
    holder = new Holder();
    holder.comment = null;
    holder.name = (TextView)row.findViewById(R.id.dealName);
    holder.degree = (TextView)row.findViewById(R.id.degree);
    holder.thermoColor = row.findViewById(R.id.thermoColor);
    holder.thermoGrey = row.findViewById(R.id.thermoGrey);
    row.setTag(holder);
}
更新

我添加了为问题作者建议的布局更改创建新支架

您需要了解,
ListView
重用视图组件。如果每个组件都创建自己的
view
,以防数百个项目,这将是一种内存浪费。这就是为什么
getView()
提供有时不为空的convertView。在这些情况下,这意味着您正在使用的视图已使用以前的数据设置

因为您使用了两种不同的布局,所以不能每次都重复使用convertView。对于这种情况,您已经实现了if语句
if(holder.comment==null&&count!=0)
。不幸的是,它只以一种方式更改布局
layoutResourceId
->
R.layout。当小布局更改为更详细的布局时,卡片行交易布局
。如果
convertView
已经是
R.layout。带有上一项和当前项数据的卡片行交易布局
应该是
layoutResourcerceId
,布局未更改。因此,您需要
holder = (Holder) row.getTag();
if(holder.comment==null && count !=0){
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    row = inflater.inflate(R.layout.card_row_deal_layout, parent, false);
    holder = new Holder();
    holder.name = (TextView)row.findViewById(R.id.dealName);
    holder.degree = (TextView)row.findViewById(R.id.degree);
    holder.thermoColor = row.findViewById(R.id.thermoColor);
    holder.thermoGrey = row.findViewById(R.id.thermoGrey);

    holder.price = (TextView) row.findViewById(R.id.price);
    holder.icon = (ImageView) row.findViewById(R.id.icon);
    holder.button = (Button) row.findViewById(R.id.toDealButton);
    holder.comment =  (TextView) row.findViewById(R.id.comment);
    row.setTag(holder);
} else if (holder.comment != null && count == 0) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    row = inflater.inflate(layoutResourceId, null);
    holder = new Holder();
    holder.comment = null;
    holder.name = (TextView)row.findViewById(R.id.dealName);
    holder.degree = (TextView)row.findViewById(R.id.degree);
    holder.thermoColor = row.findViewById(R.id.thermoColor);
    holder.thermoGrey = row.findViewById(R.id.thermoGrey);
    row.setTag(holder);
}