上下滚动时列表行背景随机变化
List row background is changing randomly when scroll up and down
我有一个列表视图,其适配器扩展了 CursorAdapter class。我可以从游标中获取数据并成功地在列表视图中显示有关电视节目的信息。我想通过查看列表中节目的开始和结束时间来标记处于活动状态的电视节目。所以我想改变活动的背景颜色。一切都是 运行 正确的,但是当我向下滚动列表时,其他一些行也被标记了。我研究了一些关于列表视图回收的文档,但我无法理解。这是我的代码:
我的适配器class:
public class StreamListAdapter extends CursorAdapter {
//............
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
ViewHolder holder = (ViewHolder)view.getTag();
Typeface fontStyle = Typeface.createFromAsset(context.getAssets(),"fonts/CenturyGothicItalic.ttf");
holder.tVName.setTypeface(fontStyle);
holder.tVBrief.setTypeface(fontStyle);
holder.tVClock.setTypeface(fontStyle);
holder.tVStat.setTypeface(fontStyle);
holder.tVGenre.setTypeface(fontStyle);
RelativeLayout rL = (RelativeLayout)view.findViewById(R.id.stream_list_item);
String title = cursor.getString(cursor.getColumnIndex("ProgramName"));
String brief = cursor.getString(cursor.getColumnIndex("ProgramBrief"));
String clock = cursor.getString(cursor.getColumnIndex("ProgramClock"));
String genre = cursor.getString(cursor.getColumnIndex("ProgramGenre"));
String stat = cursor.getString(cursor.getColumnIndex("ProgramStat"));
String imageURL = cursor.getString(cursor.getColumnIndex("ProgramImageUrl"));
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
Date dt = new Date();
String strValue = timeFormat.format(dt);
String prgStartTime = clock.substring(6, 11);
String prgEndTime = clock.substring(14);
try {
Date prgClockStart = timeFormat.parse(prgStartTime);
Date systemClock = timeFormat.parse(strValue);
Date prgClockEnd = timeFormat.parse(prgEndClock);
if(((systemClock.compareTo(prgClockStart) > 0) || (systemClock.compareTo(prgClockStart) == 0)) & (systemClock.compareTo(prgClockEnd) < 0)){
rL.setBackground(context.getResources().getDrawable(R.drawable.activegradient));
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
holder.tVName.setText(title);
holder.tVBrief.setText(brief);
holder.tVClock.setText(clock);
holder.tVStat.setText(stat);
holder.tVGenre.setText(genre);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
View row = cursorInflater.inflate(R.layout.stream_list_item, parent, false);
ViewHolder holder = new ViewHolder(row);
row.setTag(holder);
return row;
}
}
那段代码说:
if(((systemClock.compareTo(prgClockStart) > 0) || (systemClock.compareTo(prgClockStart) == 0)) & (systemClock.compareTo(prgClockEnd) < 0)){
rL.setBackground(context.getResources().getDrawable(R.drawable.activegradient));
}
需要像
这样的else块
else{
rL.setBackground( // tranparent or non-active color )
}
这是因为视图被回收了。说屏幕顶部的视图“1”滚动,如果你继续滚动,该视图最终将被回收并出现在底部准备好被反弹。
在游标适配器中,您有一种创建视图的方法和一种绑定它们的方法。如果您在代码中放置一些日志,您会看到该应用仅创建了几个视图,但在重用所有视图时多次调用 bindView。
这是因为重用一个视图比在内存中保留大量未使用的不同视图要高效得多。
简单地说——如果在 bindView 方法中有一个 "if" 块,则必须始终有一个 else。永远不要假设您的视图一开始是一片空白。
我有一个列表视图,其适配器扩展了 CursorAdapter class。我可以从游标中获取数据并成功地在列表视图中显示有关电视节目的信息。我想通过查看列表中节目的开始和结束时间来标记处于活动状态的电视节目。所以我想改变活动的背景颜色。一切都是 运行 正确的,但是当我向下滚动列表时,其他一些行也被标记了。我研究了一些关于列表视图回收的文档,但我无法理解。这是我的代码:
我的适配器class:
public class StreamListAdapter extends CursorAdapter {
//............
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
ViewHolder holder = (ViewHolder)view.getTag();
Typeface fontStyle = Typeface.createFromAsset(context.getAssets(),"fonts/CenturyGothicItalic.ttf");
holder.tVName.setTypeface(fontStyle);
holder.tVBrief.setTypeface(fontStyle);
holder.tVClock.setTypeface(fontStyle);
holder.tVStat.setTypeface(fontStyle);
holder.tVGenre.setTypeface(fontStyle);
RelativeLayout rL = (RelativeLayout)view.findViewById(R.id.stream_list_item);
String title = cursor.getString(cursor.getColumnIndex("ProgramName"));
String brief = cursor.getString(cursor.getColumnIndex("ProgramBrief"));
String clock = cursor.getString(cursor.getColumnIndex("ProgramClock"));
String genre = cursor.getString(cursor.getColumnIndex("ProgramGenre"));
String stat = cursor.getString(cursor.getColumnIndex("ProgramStat"));
String imageURL = cursor.getString(cursor.getColumnIndex("ProgramImageUrl"));
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
Date dt = new Date();
String strValue = timeFormat.format(dt);
String prgStartTime = clock.substring(6, 11);
String prgEndTime = clock.substring(14);
try {
Date prgClockStart = timeFormat.parse(prgStartTime);
Date systemClock = timeFormat.parse(strValue);
Date prgClockEnd = timeFormat.parse(prgEndClock);
if(((systemClock.compareTo(prgClockStart) > 0) || (systemClock.compareTo(prgClockStart) == 0)) & (systemClock.compareTo(prgClockEnd) < 0)){
rL.setBackground(context.getResources().getDrawable(R.drawable.activegradient));
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
holder.tVName.setText(title);
holder.tVBrief.setText(brief);
holder.tVClock.setText(clock);
holder.tVStat.setText(stat);
holder.tVGenre.setText(genre);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
View row = cursorInflater.inflate(R.layout.stream_list_item, parent, false);
ViewHolder holder = new ViewHolder(row);
row.setTag(holder);
return row;
}
}
那段代码说:
if(((systemClock.compareTo(prgClockStart) > 0) || (systemClock.compareTo(prgClockStart) == 0)) & (systemClock.compareTo(prgClockEnd) < 0)){
rL.setBackground(context.getResources().getDrawable(R.drawable.activegradient));
}
需要像
这样的else块else{
rL.setBackground( // tranparent or non-active color )
}
这是因为视图被回收了。说屏幕顶部的视图“1”滚动,如果你继续滚动,该视图最终将被回收并出现在底部准备好被反弹。
在游标适配器中,您有一种创建视图的方法和一种绑定它们的方法。如果您在代码中放置一些日志,您会看到该应用仅创建了几个视图,但在重用所有视图时多次调用 bindView。
这是因为重用一个视图比在内存中保留大量未使用的不同视图要高效得多。
简单地说——如果在 bindView 方法中有一个 "if" 块,则必须始终有一个 else。永远不要假设您的视图一开始是一片空白。