我有一个我的对象的自定义ArrayList适配器。在此适配器中,我创建一个带有arrayList deals
提供的id的游标。
我对Listview中的项有两种不同的布局,这取决于光标是否包含数据。
问题是上下滚动一段时间会导致listview在不同的项目上多次显示相同的cursordata。 arrayList中的数据显示正确。
pic:http://s1.directupload.net/images/140530/a7cz9ztt.png
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
holder = null;
Cursor cursor = null;
cursor = db.getDealInfo2ID(deals.get(position).getId());
int count = cursor.getCount();
if(row == null){
holder = new Holder();
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
if(count==0){
row = inflater.inflate(layoutResourceId, null);
holder.comment = null;
}
else{
row = inflater.inflate(R.layout.card_row_deal_layout, null);
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 = row.findViewById(R.id.thermoColor);
holder.thermoGrey = row.findViewById(R.id.thermoGrey);
row.setTag(holder);
}
else{
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.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);
}
}
//ShortCard befüllen
holder.name.setText(deals.get(position).getName());
Integer deg = deals.get(position).getDegree();
setDegreeViews(Math.abs(deg.intValue()),deg);
if(count!=0){
// DtailCard befüllen
fillDetailCard(cursor);
}
cursor.close();
return row;
}
private void fillDetailCard(Cursor cursor) {
//Preis
String priceString = cursor.getString(cursor.getColumnIndex(SQLDataBaseHelper.COLUMN_PRICE));
if(priceString!=null)
holder.price.setText(priceString);
//DirectLinkButton
String url = cursor.getString(cursor.getColumnIndex(SQLDataBaseHelper.COLUMN_DIRECTLINK));
if(url!=null){
holder.button.setText(R.string.directDeal);
holder.button.setBackgroundResource(R.drawable.to_deal_button_background);
holder.button.setOnClickListener(new ButtonDirectToListener(url, context));
}
else{
holder.button.setText("");
holder.button.setBackgroundColor(android.R.color.white);
holder.button.setOnClickListener(null);
}
//Kommentar-Anzahl
holder.comment.setText(cursor.getString(cursor.getColumnIndex(SQLDataBaseHelper.COLUMN_COMMENTCOUNT)));
//Pic
String pic = cursor.getString(cursor.getColumnIndex(SQLDataBaseHelper.COLUMN_PIC));
if(pic!=null){
holder.icon.setBackground(null);
holder.icon.setImageDrawable(null);
picasso.load(pic).error(R.drawable.error).into(holder.icon);
}
else{
holder.icon.setBackground(null);
holder.icon.setImageDrawable(null);
int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
holder.icon.setBackgroundDrawable(defaultImage);
} else {
holder.icon.setBackground(defaultImage);
}
}
cursor.close();
}
我真的不知道问题出在哪里。希望你能帮忙。
答案 0 :(得分:0)
我仔细阅读了您的代码,我发现它可能会在以下情况中发生:
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_row_deal_layout
,但您从不检查相反的方式。
看起来像这样:
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);
}
<强>更新强>
我已经添加了为问题作者建议的布局更改创建新的Holder。
您需要了解ListView
重复使用视图组件。如果每个组件都会创建自己的View
,以防数百个项目浪费内存。这就是为什么getView()
提供有时不为null的convertView的原因。在这些情况下,这意味着您正在重新使用已使用先前数据设置的视图。
因为您使用了2种不同的布局,所以每次都无法重复使用convertView。对于这种情况,您已经实现了if语句if(holder.comment==null && count !=0)
。不幸的是,它只是改变布局的一种方式layoutResourceId
- &gt; R.layout.card_row_deal_layout
当小布局变为更详细的布局时。如果convertView
已经R.layout.card_row_deal_layout
包含前一项的数据且当前项应为layoutResourceId
,则不会更改布局。因此,您需要else if
。
我希望现在很清楚。